@linzjs/step-ag-grid 29.13.0 → 29.14.1

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 (44) hide show
  1. package/dist/index.css +26 -2
  2. package/dist/src/components/Grid.d.ts +36 -61
  3. package/dist/src/components/GridRangeSelectContextMenu.d.ts +10 -0
  4. package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -1
  5. package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +2 -1
  6. package/dist/src/components/gridHook/useGridContextMenu.d.ts +12 -7
  7. package/dist/src/components/gridHook/useGridCopy.d.ts +15 -0
  8. package/dist/src/components/gridHook/useGridCopySettings.d.ts +11 -0
  9. package/dist/src/components/gridHook/useGridRangeSelection.d.ts +25 -0
  10. package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +2 -0
  11. package/dist/src/components/types.d.ts +1 -0
  12. package/dist/src/contexts/GridContext.d.ts +1 -0
  13. package/dist/src/lui/timeoutHook.d.ts +0 -6
  14. package/dist/src/lui/tsUtils.d.ts +5 -0
  15. package/dist/src/utils/__tests__/random.ts +19 -0
  16. package/dist/src/utils/util.d.ts +1 -0
  17. package/dist/step-ag-grid.cjs +560 -79
  18. package/dist/step-ag-grid.cjs.map +1 -1
  19. package/dist/step-ag-grid.esm.js +561 -82
  20. package/dist/step-ag-grid.esm.js.map +1 -1
  21. package/package.json +1 -1
  22. package/src/components/Grid.tsx +249 -179
  23. package/src/components/GridRangeSelectContextMenu.tsx +73 -0
  24. package/src/components/gridForm/GridFormDropDown.tsx +1 -3
  25. package/src/components/gridForm/GridFormPopoverMenu.tsx +2 -1
  26. package/src/components/gridHook/useGridContextMenu.tsx +22 -9
  27. package/src/components/gridHook/useGridCopy.ts +279 -0
  28. package/src/components/gridHook/useGridCopySettings.ts +28 -0
  29. package/src/components/gridHook/useGridRangeSelection.ts +235 -0
  30. package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +3 -0
  31. package/src/components/types.ts +2 -0
  32. package/src/contexts/GridContext.tsx +2 -0
  33. package/src/contexts/GridContextProvider.tsx +5 -2
  34. package/src/lui/timeoutHook.tsx +0 -19
  35. package/src/lui/tsUtils.ts +8 -0
  36. package/src/stories/grid/GridCopy.stories.tsx +175 -0
  37. package/src/stories/grid/GridPopoverEditBearing.stories.tsx +4 -4
  38. package/src/stories/grid/GridReadOnly.stories.tsx +1 -0
  39. package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +2 -2
  40. package/src/styles/ContextMenu.scss +61 -0
  41. package/src/styles/Grid.scss +26 -2
  42. package/src/utils/__tests__/random.ts +19 -0
  43. package/src/utils/bearing.ts +2 -2
  44. package/src/utils/util.ts +2 -0
@@ -419,6 +419,9 @@ function useInterval(callback, delay) {
419
419
  savedCallback.current = callback;
420
420
  }, [callback]);
421
421
  React.useEffect(() => {
422
+ if (delay === null) {
423
+ return;
424
+ }
422
425
  const id = setInterval(() => {
423
426
  savedCallback.current();
424
427
  }, delay);
@@ -435,6 +438,7 @@ const NoContext = () => {
435
438
  const GridContext = React.createContext({
436
439
  gridReady: false,
437
440
  gridRenderState: () => null,
441
+ getCellValue: NoContext,
438
442
  getColDef: NoContext,
439
443
  getColumns: NoContext,
440
444
  getColumnIds: NoContext,
@@ -756,6 +760,36 @@ const GridHeaderSelect = ({ api }) => {
756
760
  } }) }));
757
761
  };
758
762
 
763
+ function styleInject(css, ref) {
764
+ if ( ref === void 0 ) ref = {};
765
+ var insertAt = ref.insertAt;
766
+
767
+ if (!css || typeof document === 'undefined') { return; }
768
+
769
+ var head = document.head || document.getElementsByTagName('head')[0];
770
+ var style = document.createElement('style');
771
+ style.type = 'text/css';
772
+
773
+ if (insertAt === 'top') {
774
+ if (head.firstChild) {
775
+ head.insertBefore(style, head.firstChild);
776
+ } else {
777
+ head.appendChild(style);
778
+ }
779
+ } else {
780
+ head.appendChild(style);
781
+ }
782
+
783
+ if (style.styleSheet) {
784
+ style.styleSheet.cssText = css;
785
+ } else {
786
+ style.appendChild(document.createTextNode(css));
787
+ }
788
+ }
789
+
790
+ var css_248z$4 = ".GridContextMenu li.szh-menu__header{color:#6b6966;font-size:14px;font-weight:600;padding-left:16px;padding-right:16px;text-transform:none}.GridContextMenu li.szh-menu__item{padding-left:16px;padding-right:16px}.GridContextMenu li.szh-menu__item .copyMenuMenuItem{align-items:center;display:flex;gap:8px}.GridContextMenu li.szh-menu__item .copyMenuMenuItem__text{color:#2a292c;font-size:16px;font-weight:400;width:80px}.GridContextMenu li.szh-menu__item .copyMenuMenuItem__buttonDefault{background:none;border:2px solid #0000;display:flex;padding:6px}.GridContextMenu li.szh-menu__item .copyMenuMenuItem__buttonDefault.copyMenuMenuItem__buttonDefault--hidden:hover{border:2px solid #2a292c}.GridContextMenu li.szh-menu__item .copyMenuMenuItem__buttonDefault--hidden .LuiIcon{fill:#0000}.GridContextMenu li.szh-menu__item .LuiIcon,.GridContextMenu li.szh-menu__item .copyMenuMenuItem__buttonDefault--hidden:hover .LuiIcon{fill:#6b6966}.GridContextMenu li.szh-menu__item .LuiIcon[data-icon=ic_tick]{padding-left:4px;padding-right:4px}.GridContextMenu li.szh-menu__item--hover{background-color:#e2f3f7}";
791
+ styleInject(css_248z$4);
792
+
759
793
  const EventHandlersContext = React.createContext({
760
794
  handleClick: () => { },
761
795
  });
@@ -2590,7 +2624,7 @@ const SubMenuFr = ({ 'aria-label': ariaLabel, className, disabled, direction, la
2590
2624
  };
2591
2625
  const SubMenu = withHovering('SubMenu', SubMenuFr);
2592
2626
 
2593
- const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, }) => {
2627
+ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, context, }) => {
2594
2628
  const { redrawRows, prePopupOps, resetFocusedCellAfterCellEditing, getSelectedRows } = React.useContext(GridContext);
2595
2629
  const [isOpen, setOpen] = React.useState(false);
2596
2630
  const [anchorPoint, setAnchorPoint] = React.useState({ x: 0, y: 0 });
@@ -2598,6 +2632,7 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
2598
2632
  const clickedColDefRef = React.useRef(null);
2599
2633
  const selectedRowsRef = React.useRef([]);
2600
2634
  const clickedRowRef = React.useRef(null);
2635
+ const eventRef = React.useRef(undefined);
2601
2636
  const openMenu = React.useCallback((e) => {
2602
2637
  if (!e)
2603
2638
  return;
@@ -2617,15 +2652,423 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
2617
2652
  clickedColDefRef.current = event.colDef;
2618
2653
  selectedRowsRef.current = getSelectedRows();
2619
2654
  clickedRowRef.current = event.data;
2655
+ eventRef.current = event;
2620
2656
  // This is actually a pointer event
2621
2657
  openMenu(event.event);
2622
2658
  }, [contextMenuSelectRow, getSelectedRows, openMenu]);
2623
2659
  return {
2624
2660
  openMenu,
2625
2661
  cellContextMenu,
2626
- component: ContextMenu ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(ControlledMenu, { anchorPoint: anchorPoint, state: isOpen ? 'open' : 'closed', direction: "right", onClose: closeMenu, children: isOpen && (jsxRuntime.jsx(ContextMenu, { selectedRows: selectedRowsRef.current, clickedRow: clickedRowRef.current, colDef: clickedColDefRef.current, close: closeMenu })) }) })) : null,
2662
+ contextMenuComponent: ContextMenu ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(ControlledMenu, { className: 'GridContextMenu', anchorPoint: anchorPoint, state: isOpen ? 'open' : 'closed', direction: "right", onClose: closeMenu, children: isOpen && (jsxRuntime.jsx(ContextMenu, { selectedRows: selectedRowsRef.current, clickedRow: clickedRowRef.current, colDef: clickedColDefRef.current, event: eventRef.current, close: closeMenu, context: context })) }) })) : null,
2663
+ };
2664
+ };
2665
+
2666
+ const typedEntries = (obj) => Object.entries(obj);
2667
+
2668
+ const gridCopyOptions = {
2669
+ html: { text: 'Text\xa0/\xa0HTML', icon: 'ic_product_list' },
2670
+ csv: { text: 'CSV', icon: 'ic_csv_file' },
2671
+ json: { text: 'Json', icon: 'ic_file_attached_outline', developer: true },
2672
+ };
2673
+ const CopyOptionsStorageKey = 'stepAgGrid_defaultCopy';
2674
+ const useGridCopySettings = () => {
2675
+ const [copyType, _setCopyType] = React.useState(() => {
2676
+ const defaultCopy = window.localStorage.getItem(CopyOptionsStorageKey) ?? '';
2677
+ return Object.keys(gridCopyOptions).includes(defaultCopy) ? defaultCopy : 'html';
2678
+ });
2679
+ const setCopyType = React.useCallback((key) => {
2680
+ window.localStorage.setItem(CopyOptionsStorageKey, key);
2681
+ _setCopyType(key);
2682
+ }, []);
2683
+ return {
2684
+ copyType,
2685
+ setCopyType,
2686
+ };
2687
+ };
2688
+
2689
+ const GridRangeSelectContextMenu = ({ event, context, }) => {
2690
+ const developerContextMenu = !!event?.event?.ctrlKey && !!event?.event?.shiftKey;
2691
+ const onCopy = React.useMemo(() => context?.onCopy, [context?.onCopy]);
2692
+ const onClick = React.useCallback((type) => {
2693
+ onCopy?.(type);
2694
+ }, [onCopy]);
2695
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(MenuHeader, { children: "Copy as" }), typedEntries(gridCopyOptions).map(([key, { icon, text, developer }]) => {
2696
+ return ((!developer || developerContextMenu) && (jsxRuntime.jsx(MenuItem, { onClick: () => void onClick(key), children: jsxRuntime.jsxs("div", { className: 'copyMenuMenuItem', children: [jsxRuntime.jsx(lui.LuiIcon, { name: icon, alt: text, size: 'md' }), jsxRuntime.jsx("div", { className: 'copyMenuMenuItem__text', children: text })] }) }, key)));
2697
+ }), jsxRuntime.jsx(MenuDivider, {}), jsxRuntime.jsx(MenuHeader, { children: "Set copy default" }), typedEntries(gridCopyOptions).map(([key, { text, developer }]) => {
2698
+ return (!developer && (jsxRuntime.jsx(MenuItem, { onClick: (e) => {
2699
+ context?.setCopyType(key);
2700
+ e.keepOpen = true;
2701
+ }, children: jsxRuntime.jsxs("div", { className: clsx('copyMenuMenuItem', context?.copyType === key ? '' : 'copyMenuMenuItem__buttonDefault--hidden'), children: [jsxRuntime.jsx(lui.LuiIcon, { name: 'ic_tick', alt: 'CSV', size: 'sm' }), jsxRuntime.jsx("div", { className: 'copyMenuMenuItem__text', children: text })] }) }, 'default_' + key)));
2702
+ })] }));
2703
+ };
2704
+
2705
+ const agGridSelectRowColId = 'ag-Grid-SelectionColumn';
2706
+
2707
+ const useGridCopy = ({ ranges, rangeStartRef, rangeEndRef, hasSelectedMoreThanOneCellRef, cellContextMenu, }) => {
2708
+ const showToast = lui.useShowLUIMessage();
2709
+ const { getSelectedRowIds } = useGridContext();
2710
+ const { getColDef, getCellValue } = useGridContext();
2711
+ const { copyType, setCopyType } = useGridCopySettings();
2712
+ const onCopy = React.useCallback((type = copyType) => {
2713
+ const rangeStart = rangeStartRef.current;
2714
+ const rangeEnd = rangeEndRef.current;
2715
+ if (rangeStart === null || rangeEnd === null || !hasSelectedMoreThanOneCellRef.current) {
2716
+ return;
2717
+ }
2718
+ if (rangeStart.rowId === rangeEnd.rowId && rangeStart.colId === rangeEnd.colId) {
2719
+ type = 'html';
2720
+ }
2721
+ const json = type === 'json';
2722
+ const { selectedColIds, selectedNodes } = ranges();
2723
+ const filteredSelectedColIds = selectedColIds.filter((colId) => colId === agGridSelectRowColId ||
2724
+ (colId !== 'gridCellFiller' && getColDef(colId)?.headerComponentParams?.exportable !== false));
2725
+ const selectedRowIds = getSelectedRowIds();
2726
+ const formatters = lodashEs.compact(filteredSelectedColIds.map((colKey) => {
2727
+ return (rowNode) => {
2728
+ if (colKey === agGridSelectRowColId) {
2729
+ return selectedRowIds.includes(rowNode.data.id);
2730
+ }
2731
+ else {
2732
+ const v = getCellValue({ rowNode, colKey });
2733
+ if (json && v !== undefined) {
2734
+ return v;
2735
+ }
2736
+ const f = getCellValue({ rowNode, colKey, useFormatter: true });
2737
+ // If it's a number, and it matches value return the original type
2738
+ return v == f ? v : f;
2739
+ }
2740
+ };
2741
+ }));
2742
+ // Get and apply headers
2743
+ const headers = filteredSelectedColIds.map((colId) => {
2744
+ if (colId === agGridSelectRowColId)
2745
+ return type === 'json' ? 'selected' : 'Selected';
2746
+ if (json) {
2747
+ return colId;
2748
+ }
2749
+ return getColDef(colId)?.headerName ?? '?';
2750
+ });
2751
+ const maxCellLength = {};
2752
+ headers.forEach((headerName, i) => {
2753
+ const colId = filteredSelectedColIds[i];
2754
+ maxCellLength[colId] = headerName.length;
2755
+ });
2756
+ const rows = [];
2757
+ if (type === 'csv' || type === 'html') {
2758
+ rows.push(headers);
2759
+ }
2760
+ selectedNodes.forEach((node) => {
2761
+ const row = [];
2762
+ rows.push(row);
2763
+ formatters.forEach((formatter, i) => {
2764
+ const colId = filteredSelectedColIds[i];
2765
+ let value = formatter(node);
2766
+ if (typeof value === 'string') {
2767
+ value = value.replaceAll('\xa0', ' ');
2768
+ }
2769
+ if (!json) {
2770
+ if (value === '-' || value === '–' || value == null) {
2771
+ value = '';
2772
+ }
2773
+ value = String(value);
2774
+ if (value === '-' || value === '–') {
2775
+ value = '';
2776
+ }
2777
+ maxCellLength[colId] = Math.max(maxCellLength[colId], value.length);
2778
+ }
2779
+ switch (type) {
2780
+ case 'json':
2781
+ value =
2782
+ value === 'undefined' || (value !== null && typeof value === 'object') || typeof value === 'string'
2783
+ ? JSON.stringify(value)
2784
+ : value;
2785
+ break;
2786
+ case 'markdown':
2787
+ value = encodeMarkdownValue(value);
2788
+ break;
2789
+ case 'csv':
2790
+ value = encodeCSVValue(value);
2791
+ break;
2792
+ }
2793
+ row.push(String(value));
2794
+ });
2795
+ });
2796
+ let result = '';
2797
+ let html = `<table style="
2798
+ font-family: 'Open Sans', system-ui, sans-serif;
2799
+ font-size: 10px;
2800
+ line-height: 10px;
2801
+ border: 1px solid #d1d9e0;
2802
+ border-collapse: collapse;
2803
+ ">`;
2804
+ if (json) {
2805
+ result += '[\n';
2806
+ }
2807
+ rows.forEach((row, rowIndex) => {
2808
+ if (json) {
2809
+ result += ' { ';
2810
+ }
2811
+ if (rowIndex == 1) {
2812
+ html += '<tbody style="font-weight: 400;">';
2813
+ }
2814
+ if (rowIndex == 0) {
2815
+ html += '<thead style="font-weight: 600;">';
2816
+ }
2817
+ if (rowIndex === 0 || (rowIndex & 1) === 1) {
2818
+ html += '<tr>';
2819
+ }
2820
+ else {
2821
+ html += '<tr style="background-color: #f6f8fa;">';
2822
+ }
2823
+ if (rowIndex === 1 && type === 'html') {
2824
+ Object.values(maxCellLength).forEach((maxLength) => {
2825
+ result += '|' + '-'.repeat(maxLength + 2);
2826
+ });
2827
+ result += '|\n';
2828
+ }
2829
+ row.forEach((cell, i) => {
2830
+ switch (type) {
2831
+ case 'csv':
2832
+ if (i !== 0) {
2833
+ result += ', ';
2834
+ }
2835
+ result += cell;
2836
+ break;
2837
+ case 'html':
2838
+ if (i === 0) {
2839
+ result += '|';
2840
+ }
2841
+ const colId = filteredSelectedColIds[i];
2842
+ result += ' ' + cell.padEnd(maxCellLength[colId], ' ') + ' ';
2843
+ result += '|';
2844
+ html +=
2845
+ rowIndex === 0
2846
+ ? '<th style="border: 1px solid #d1d9e0; padding:6px 13px; text-align: left;">'
2847
+ : '<td style="border: 1px solid #d1d9e0; padding:6px 13px;">';
2848
+ html += cell;
2849
+ html += rowIndex === 0 ? '</th>' : '</td>';
2850
+ break;
2851
+ case 'json':
2852
+ if (i !== 0) {
2853
+ result += ', ';
2854
+ }
2855
+ result += JSON.stringify(headers[i]) + ': ' + cell;
2856
+ break;
2857
+ }
2858
+ });
2859
+ html += '</tr>';
2860
+ if (rowIndex == 0) {
2861
+ html += '</thead>';
2862
+ }
2863
+ if (rowIndex == rows.length - 1) {
2864
+ html += '</tbody>';
2865
+ }
2866
+ if (json) {
2867
+ result += ' }';
2868
+ }
2869
+ result += '\n';
2870
+ });
2871
+ if (json) {
2872
+ result += ']\n';
2873
+ }
2874
+ html += '</table>';
2875
+ showToast({
2876
+ message: `${gridCopyOptions[type].text} copied`,
2877
+ messageType: 'toast',
2878
+ messageLevel: 'info',
2879
+ });
2880
+ if (type === 'html') {
2881
+ const clipboardItem = new ClipboardItem({
2882
+ 'text/html': new Blob([html], { type: 'text/html' }),
2883
+ 'text/plain': new Blob([result], { type: 'text/plain' }), // fallback
2884
+ });
2885
+ void navigator.clipboard.write([clipboardItem]).catch((err) => console.error('Failed to copy: ', err));
2886
+ }
2887
+ else {
2888
+ void navigator.clipboard.writeText(result).catch((err) => console.error('Failed to copy: ', err));
2889
+ }
2890
+ }, [getCellValue, ranges, copyType]);
2891
+ const onCopyEvent = React.useCallback((e) => {
2892
+ const rangeStart = rangeStartRef.current;
2893
+ const rangeEnd = rangeEndRef.current;
2894
+ if (rangeStart === null ||
2895
+ rangeEnd === null ||
2896
+ (rangeStart.colId === rangeEnd.colId &&
2897
+ rangeStart.rowId === rangeEnd.rowId &&
2898
+ !hasSelectedMoreThanOneCellRef.current)) {
2899
+ return;
2900
+ }
2901
+ e.preventDefault();
2902
+ onCopy();
2903
+ }, [onCopy]);
2904
+ const { cellContextMenu: rangeSelectContextMenu, contextMenuComponent: rangeSelectContextMenuComponent } = useGridContextMenu({
2905
+ contextMenu: (GridRangeSelectContextMenu),
2906
+ context: { onCopy, copyType, setCopyType },
2907
+ });
2908
+ const rangeSelectInterceptContextMenu = React.useCallback((event) => rangeStartRef.current == null ? cellContextMenu(event) : rangeSelectContextMenu(event), [cellContextMenu, rangeSelectContextMenu]);
2909
+ return {
2910
+ onCopyEvent,
2911
+ rangeSelectInterceptContextMenu,
2912
+ rangeSelectContextMenuComponent,
2627
2913
  };
2628
2914
  };
2915
+ const encodeMarkdownValue = (value) => {
2916
+ return value.replaceAll('|', '\\|');
2917
+ };
2918
+ const encodeCSVValue = (value) => {
2919
+ let str = String(value);
2920
+ // Check if it needs quoting
2921
+ if (/[",\n]/.test(str)) {
2922
+ // Escape double quotes by doubling them
2923
+ str = '"' + str.replace(/"/g, '""') + '"';
2924
+ }
2925
+ return str;
2926
+ };
2927
+
2928
+ const useGridRangeSelection = ({ enableRangeSelection, gridDivRef, rangeStartRef, rangeEndRef, hasSelectedMoreThanOneCellRef, rangeSortedNodesRef, }) => {
2929
+ const [refreshIntervalEnabled, setRefreshIntervalEnabled] = React.useState(false);
2930
+ const ranges = React.useCallback(() => {
2931
+ const gridElement = gridDivRef.current;
2932
+ const rangeStart = rangeStartRef.current;
2933
+ const rangeEnd = rangeEndRef.current;
2934
+ const rangeSortedNodes = rangeSortedNodesRef.current;
2935
+ if (!gridElement || !rangeStart || !rangeEnd || !rangeSortedNodes) {
2936
+ return {
2937
+ selectedColIds: [],
2938
+ selectedNodes: [],
2939
+ };
2940
+ }
2941
+ const elStyleLeftComparator = (el1, el2) => elStyleLeft(el1) - elStyleLeft(el2);
2942
+ const elStyleLeft = (el) => parseFloat(el.style.left) ?? 0;
2943
+ const getSortedColIds = () => {
2944
+ //
2945
+ const leftHeaders = [...gridElement.querySelectorAll('.ag-pinned-left-header .ag-header-cell')].sort(elStyleLeftComparator);
2946
+ const centerHeaders = [...gridElement.querySelectorAll('.ag-header-viewport .ag-header-cell')].sort(elStyleLeftComparator);
2947
+ const rightHeaders = [...gridElement.querySelectorAll('.ag-pinned-right-header .ag-header-cell')].sort(elStyleLeftComparator);
2948
+ return [...leftHeaders, ...centerHeaders, ...rightHeaders].map((el, i) => el.getAttribute('col-id') ?? String(i));
2949
+ };
2950
+ const sortedColIds = getSortedColIds();
2951
+ const startColIndex = sortedColIds.indexOf(rangeStart.colId);
2952
+ const endColIndex = sortedColIds.indexOf(rangeEnd.colId);
2953
+ const selectedColIds = sortedColIds.slice(Math.min(startColIndex, endColIndex), Math.max(startColIndex, endColIndex) + 1);
2954
+ const startRowIndex = rangeSortedNodes.findIndex((node) => node.data.id === rangeStart.rowId);
2955
+ const endRowIndex = rangeSortedNodes.findIndex((node) => node.data.id === rangeEnd.rowId);
2956
+ const selectedNodes = rangeSortedNodes.slice(Math.min(startRowIndex, endRowIndex), Math.max(startRowIndex, endRowIndex) + 1);
2957
+ return { selectedColIds, selectedNodes };
2958
+ }, []);
2959
+ const redrawSelectedRanges = React.useCallback(() => {
2960
+ const gridElement = gridDivRef.current;
2961
+ const { selectedColIds, selectedNodes } = ranges();
2962
+ selectedColIds.forEach((colId, colIndex) => {
2963
+ selectedNodes.forEach((node, rowIndex) => {
2964
+ const rowId = node.data.id;
2965
+ const cell = gridElement.querySelector(`.ag-row[row-id=${JSON.stringify(String(rowId))}] .ag-cell[col-id=${JSON.stringify(colId)}`);
2966
+ cell?.classList.add('rangeSelect');
2967
+ if (colIndex === 0) {
2968
+ cell?.classList.add('rangeSelectLeft');
2969
+ }
2970
+ if (colIndex === selectedColIds.length - 1) {
2971
+ cell?.classList.add('rangeSelectRight');
2972
+ }
2973
+ if (rowIndex === 0) {
2974
+ cell?.classList.add('rangeSelectTop');
2975
+ }
2976
+ if (rowIndex === selectedNodes.length - 1) {
2977
+ cell?.classList.add('rangeSelectBottom');
2978
+ }
2979
+ });
2980
+ });
2981
+ }, []);
2982
+ const updateRangeSelectionCellClasses = React.useCallback((justRefresh) => {
2983
+ //
2984
+ // Get all grid cols, sort by pinned, then style: left
2985
+ const gridElement = gridDivRef.current;
2986
+ if (!gridElement) {
2987
+ return;
2988
+ }
2989
+ // Clear all selections
2990
+ if (!justRefresh) {
2991
+ gridElement
2992
+ .querySelectorAll('.rangeSelect,.rangeSelectLeft,.rangeSelectTop,.rangeSelectRight,.rangeSelectBottom')
2993
+ .forEach((el) => {
2994
+ el.classList.remove('rangeSelect', 'rangeSelectLeft', 'rangeSelectTop', 'rangeSelectRight', 'rangeSelectBottom');
2995
+ });
2996
+ }
2997
+ // if range selection multiple add .Grid-container.rangeSelectingMultiple
2998
+ const rangeStart = rangeStartRef.current;
2999
+ const rangeEnd = rangeEndRef.current;
3000
+ if (rangeStart !== null &&
3001
+ rangeEnd !== null &&
3002
+ (hasSelectedMoreThanOneCellRef.current ||
3003
+ rangeStart.colId !== rangeEnd.colId ||
3004
+ rangeStart.rowId !== rangeEnd.rowId)) {
3005
+ gridElement.classList.add('rangeSelectingMultiple');
3006
+ gridElement.querySelectorAll('.ag-cell-focus').forEach((el) => {
3007
+ el.classList.remove('ag-cell-focus');
3008
+ });
3009
+ }
3010
+ else {
3011
+ gridElement.classList.remove('rangeSelectingMultiple');
3012
+ return;
3013
+ }
3014
+ const rangeSortedNodes = rangeSortedNodesRef.current;
3015
+ if (!rangeSortedNodes) {
3016
+ return;
3017
+ }
3018
+ redrawSelectedRanges();
3019
+ }, [ranges, redrawSelectedRanges]);
3020
+ // Handle updates after scroll / grid refresh
3021
+ useInterval(() => {
3022
+ updateRangeSelectionCellClasses(true);
3023
+ }, refreshIntervalEnabled ? 150 : null);
3024
+ const clearRangeSelection = React.useCallback(() => {
3025
+ hasSelectedMoreThanOneCellRef.current = false;
3026
+ setRefreshIntervalEnabled(false);
3027
+ hasSelectedMoreThanOneCellRef.current = false;
3028
+ rangeStartRef.current = null;
3029
+ rangeEndRef.current = null;
3030
+ updateRangeSelectionCellClasses();
3031
+ }, [updateRangeSelectionCellClasses]);
3032
+ const onCellMouseOver = React.useCallback((e, mouseDown) => {
3033
+ if (!enableRangeSelection) {
3034
+ return;
3035
+ }
3036
+ const button = e.event.buttons;
3037
+ if (button !== 1) {
3038
+ // TODO fix this?
3039
+ //rangeSortedNodesRef.current = null;
3040
+ return;
3041
+ }
3042
+ rangeEndRef.current = {
3043
+ rowId: e.node.data.id,
3044
+ colId: e.column.getColId(),
3045
+ timestamp: Date.now(),
3046
+ };
3047
+ if (mouseDown) {
3048
+ const sortedNodes = [];
3049
+ e.api.forEachNodeAfterFilterAndSort((node) => sortedNodes.push(node));
3050
+ rangeSortedNodesRef.current = sortedNodes;
3051
+ setRefreshIntervalEnabled(true);
3052
+ rangeStartRef.current = { ...rangeEndRef.current };
3053
+ }
3054
+ if (rangeStartRef.current &&
3055
+ rangeEndRef.current &&
3056
+ (rangeStartRef.current.rowId !== rangeEndRef.current.rowId ||
3057
+ rangeStartRef.current.colId !== rangeEndRef.current.colId)) {
3058
+ hasSelectedMoreThanOneCellRef.current = true;
3059
+ window.getSelection()?.removeAllRanges();
3060
+ }
3061
+ updateRangeSelectionCellClasses();
3062
+ }, [enableRangeSelection, updateRangeSelectionCellClasses]);
3063
+ const onCellMouseDown = React.useCallback((e) => {
3064
+ const button = e.event.buttons;
3065
+ if (button === 1) {
3066
+ clearRangeSelection();
3067
+ }
3068
+ onCellMouseOver(e, true);
3069
+ }, [onCellMouseOver]);
3070
+ return { clearRangeSelection, ranges, onCellMouseDown, onCellMouseOver };
3071
+ };
2629
3072
 
2630
3073
  const GridLoadingOverlayComponentFr = (props, externalRef) => (jsxRuntime.jsx("div", { ref: externalRef, style: {
2631
3074
  left: 0,
@@ -2808,8 +3251,26 @@ agGridCommunity.ModuleRegistry.registerModules([agGridCommunity.AllCommunityModu
2808
3251
  /**
2809
3252
  * Wrapper for AgGrid to add commonly used functionality.
2810
3253
  */
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 }) => {
2812
- const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass, setOnBulkEditingComplete, getColDef, showNoRowsOverlay, prePopupOps, startCellEditing: propStartCellEditing, } = useGridContext();
3254
+ const Grid = ({ theme = 'ag-theme-step-default', 'data-testid': dataTestId,
3255
+ // ─── Grid State ───────────────────────────────
3256
+ suppressReadOnlyStyle = false,
3257
+ // ─── Data & Columns ───────────────────────────
3258
+ defaultPostSort = true, rowData, rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40, rowSelection = 'multiple', sizeColumns = 'auto',
3259
+ // ─── Selection ────────────────────────────────
3260
+ autoSelectFirstRow, enableRangeSelection = false, externalSelectedIds, externalSelectedItems, selectColumnPinned = 'left', selectable, setExternalSelectedIds, setExternalSelectedItems,
3261
+ // ─── Editing ──────────────────────────────────
3262
+ singleClickEdit = false,
3263
+ // ─── Context Menu ─────────────────────────────
3264
+ contextMenuSelectRow = false, contextMenu,
3265
+ // ─── Callbacks / Events ───────────────────────
3266
+ onCellFocused: paramsOnCellFocused, onColumnMoved,
3267
+ // ─── Row Behavior ─────────────────────────────
3268
+ suppressColumnVirtualization = true,
3269
+ // ─── Miscellaneous ────────────────────────────
3270
+ maxInitialWidth,
3271
+ // ─── Spread Remaining Params ──────────────────
3272
+ ...params }) => {
3273
+ const { setApis, setExternallySelectedItemsAreInSync, setOnBulkEditingComplete, gridReady, gridRenderState, externallySelectedItemsAreInSync, showNoRowsOverlay, autoSizeColumns, sizeColumnsToFit, doesExternalFilterPass, ensureRowVisible, ensureSelectedRowIsVisible, focusByRowById, getColDef, getFirstRowId, isExternalFilterPresent, prePopupOps, selectRowsById, startCellEditing: propStartCellEditing, } = useGridContext();
2813
3274
  // CellEditingStop event happens too much for one edit
2814
3275
  const startedEditRef = React.useRef(false);
2815
3276
  const startCellEditing = React.useCallback((props) => {
@@ -2948,7 +3409,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2948
3409
  return;
2949
3410
  }
2950
3411
  hasSelectedFirstItem.current = true;
2951
- if (isNotEmpty(rowData) && lodashEs.isEmpty(externalSelectedItems)) {
3412
+ if (isNotEmpty(rowData) && lodashEs.isEmpty(externalSelectedItems) && lodashEs.isEmpty(externalSelectedIds)) {
2952
3413
  const firstRowId = getFirstRowId();
2953
3414
  if (autoSelectFirstRow && selectable) {
2954
3415
  selectRowsById([firstRowId]);
@@ -2967,6 +3428,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
2967
3428
  selectRowsById,
2968
3429
  getFirstRowId,
2969
3430
  selectable,
3431
+ externalSelectedIds,
2970
3432
  ]);
2971
3433
  /**
2972
3434
  * Ensure external selected items list is in sync with panel.
@@ -3130,15 +3592,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3130
3592
  void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
3131
3593
  }
3132
3594
  }, [startCellEditing]);
3133
- /**
3134
- * Handle single click edits
3135
- */
3136
- const onCellClicked = React.useCallback((event) => {
3137
- const editable = fnOrVar(event.colDef?.editable, event);
3138
- if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
3139
- void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
3140
- }
3141
- }, [singleClickEdit, startCellEditing]);
3142
3595
  const onCellEditingStopped = React.useCallback((event) => {
3143
3596
  if (!startedEditRef.current) {
3144
3597
  return;
@@ -3187,6 +3640,78 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3187
3640
  prePopupOps();
3188
3641
  }
3189
3642
  }, [prePopupOps, startCellEditing]);
3643
+ const { cellContextMenu, contextMenuComponent } = useGridContextMenu({
3644
+ contextMenu,
3645
+ contextMenuSelectRow,
3646
+ });
3647
+ const hasSelectedMoreThanOneCellRef = React.useRef(false);
3648
+ const rangeStartRef = React.useRef(null);
3649
+ const rangeEndRef = React.useRef(null);
3650
+ const rangeSortedNodesRef = React.useRef(null);
3651
+ const { clearRangeSelection, ranges, onCellMouseDown, onCellMouseOver } = useGridRangeSelection({
3652
+ enableRangeSelection,
3653
+ gridDivRef,
3654
+ rangeStartRef,
3655
+ rangeEndRef,
3656
+ hasSelectedMoreThanOneCellRef,
3657
+ rangeSortedNodesRef,
3658
+ });
3659
+ const { onCopyEvent, rangeSelectInterceptContextMenu, rangeSelectContextMenuComponent } = useGridCopy({
3660
+ ranges,
3661
+ rangeStartRef,
3662
+ rangeEndRef,
3663
+ hasSelectedMoreThanOneCellRef,
3664
+ cellContextMenu,
3665
+ });
3666
+ const onSortChanged = React.useCallback(() => {
3667
+ clearRangeSelection();
3668
+ ensureSelectedRowIsVisible();
3669
+ }, [clearRangeSelection, ensureSelectedRowIsVisible]);
3670
+ /**
3671
+ * Handle single click edits
3672
+ */
3673
+ const onCellClicked = React.useCallback((event) => {
3674
+ if (rangeStartRef.current && rangeEndRef.current) {
3675
+ // This is to detect difference between a single click and a click drag return to cell.
3676
+ if (rangeEndRef.current.timestamp - rangeStartRef.current.timestamp < 100) {
3677
+ clearRangeSelection();
3678
+ }
3679
+ return;
3680
+ }
3681
+ const editable = fnOrVar(event.colDef?.editable, event);
3682
+ if ((editable && event.colDef.singleClickEdit) ?? singleClickEdit) {
3683
+ void startCellEditing({ rowId: event.data.id, colId: event.column.getColId() });
3684
+ }
3685
+ }, [clearRangeSelection, singleClickEdit, startCellEditing]);
3686
+ /**
3687
+ * Set of column I'd's that are prevented from auto-sizing as they are user set
3688
+ */
3689
+ const userSizedColIds = React.useRef(new Map());
3690
+ /**
3691
+ * Lock/unlock column width on user edit/reset.
3692
+ */
3693
+ const onColumnResized = React.useCallback((e) => {
3694
+ const colId = e.column?.getColId();
3695
+ if (colId == null) {
3696
+ return;
3697
+ }
3698
+ const width = e.column?.getActualWidth();
3699
+ if (width == null) {
3700
+ return;
3701
+ }
3702
+ switch (e.source) {
3703
+ case 'uiColumnResized':
3704
+ userSizedColIds.current.set(colId, width);
3705
+ break;
3706
+ case 'autosizeColumns':
3707
+ userSizedColIds.current.delete(colId);
3708
+ break;
3709
+ }
3710
+ }, []);
3711
+ const columnMoved = React.useCallback((e) => {
3712
+ clearRangeSelection();
3713
+ onColumnMoved?.(e);
3714
+ }, [clearRangeSelection, onColumnMoved]);
3190
3715
  /**
3191
3716
  * Once the grid has auto-sized we want to run fit to fit the grid in its container,
3192
3717
  * but we don't want the non-flex auto-sized columns to "fit" size, so suppressSizeToFit is set to true.
@@ -3294,37 +3819,6 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3294
3819
  }
3295
3820
  prevLoading.current = newLoading;
3296
3821
  }, [params.loading, rowData, showNoRowsOverlay]);
3297
- /**
3298
- * Set of column I'd's that are prevented from auto-sizing as they are user set
3299
- */
3300
- const userSizedColIds = React.useRef(new Map());
3301
- /**
3302
- * Lock/unlock column width on user edit/reset.
3303
- */
3304
- const onColumnResized = React.useCallback((e) => {
3305
- const colId = e.column?.getColId();
3306
- if (colId == null) {
3307
- return;
3308
- }
3309
- const width = e.column?.getActualWidth();
3310
- if (width == null) {
3311
- return;
3312
- }
3313
- switch (e.source) {
3314
- case 'uiColumnResized':
3315
- userSizedColIds.current.set(colId, width);
3316
- /*const colDef = e.column?.getColDef();
3317
- if (!colDef?.flex) {
3318
- onGridResize(e);
3319
- }*/
3320
- break;
3321
- case 'autosizeColumns':
3322
- userSizedColIds.current.delete(colId);
3323
- //onGridResize(e);
3324
- break;
3325
- }
3326
- }, []);
3327
- const gridContextMenu = useGridContextMenu({ contextMenu: params.contextMenu, contextMenuSelectRow });
3328
3822
  const startDragYRef = React.useRef(null);
3329
3823
  const clearHighlightRowClasses = React.useCallback(() => {
3330
3824
  document.querySelectorAll(`.ag-row-highlight-above`)?.forEach((el) => {
@@ -3452,15 +3946,24 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3452
3946
  }
3453
3947
  return false;
3454
3948
  },
3455
- onCellClicked: clickInputWhenContainingCellClicked,
3949
+ // enableClickSelection = true means ag-grid auto selects row if you click outside the checkbox
3950
+ // if it's false we have to do it.
3951
+ onCellClicked: params.enableClickSelection ? undefined : clickInputWhenContainingCellClicked,
3456
3952
  };
3457
- }, [params.hideSelectColumn, params.onRowDragEnd, rowSelection, selectColumnPinned, selectable]);
3953
+ }, [
3954
+ params.hideSelectColumn,
3955
+ params.onRowDragEnd,
3956
+ rowSelection,
3957
+ selectColumnPinned,
3958
+ selectable,
3959
+ params.enableClickSelection,
3960
+ ]);
3458
3961
  const onGridSizeChanged = React.useCallback((event) => {
3459
3962
  if (sizeColumns === 'fit' || (['auto', 'auto-skip-headers'].includes(sizeColumns) && hasSetContentSize.current)) {
3460
3963
  event.api.sizeColumnsToFit();
3461
3964
  }
3462
3965
  }, [sizeColumns]);
3463
- return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [gridContextMenu.component, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsxRuntime.jsx(agGridReact.AgGridReact, { theme: 'legacy', rowSelection: selectable
3966
+ return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [contextMenuComponent, rangeSelectContextMenuComponent, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, onCopy: onCopyEvent, children: jsxRuntime.jsx(agGridReact.AgGridReact, { theme: 'legacy', domLayout: params.domLayout, defaultColDef: defaultColDef, columnDefs: columnDefsAdjusted, getRowId: getRowId, rowData: rowData, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, animateRows: params.animateRows ?? false, doesExternalFilterPass: doesExternalFilterPass, isExternalFilterPresent: isExternalFilterPresent, maintainColumnOrder: true, noRowsOverlayComponent: noRowsOverlayComponent, onCellClicked: onCellClicked, onCellContextMenu: rangeSelectInterceptContextMenu, onCellDoubleClicked: onCellDoubleClick, onCellEditingStopped: onCellEditingStopped, onCellFocused: onCellFocused, onCellKeyDown: onCellKeyPress, onCellMouseDown: onCellMouseDown, onCellMouseOver: onCellMouseOver, onColumnMoved: columnMoved, onColumnResized: onColumnResized, onColumnVisible: () => void setInitialContentSize(), onGridReady: onGridReady, onGridSizeChanged: onGridSizeChanged, onModelUpdated: onModelUpdated, onRowClicked: params.onRowClicked, onRowDataUpdated: onRowDataUpdated, onRowDoubleClicked: params.onRowDoubleClicked, onRowDragCancel: clearHighlightRowClasses, onRowDragEnd: onRowDragEnd, onRowDragMove: onRowDragMove, onSelectionChanged: synchroniseExternalStateToGridSelection, onSortChanged: onSortChanged, pinnedBottomRowData: params.pinnedBottomRowData, pinnedTopRowData: params.pinnedTopRowData, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, preventDefaultOnContextMenu: true, quickFilterParser: quickFilterParser, rowClassRules: params.rowClassRules, rowDragText: params.rowDragText, rowHeight: rowHeight, rowSelection: selectable
3464
3967
  ? {
3465
3968
  enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
3466
3969
  enableClickSelection: params.enableClickSelection ?? false,
@@ -3470,7 +3973,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
3470
3973
  headerCheckbox: false,
3471
3974
  }),
3472
3975
  }
3473
- : undefined, selectionColumnDef: selectionColumnDef, rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId: getRowId, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onGridSizeChanged: onGridSizeChanged, onColumnVisible: () => void setInitialContentSize(), onRowDataUpdated: onRowDataUpdated, onCellFocused: onCellFocused, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStopped: onCellEditingStopped, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: defaultColDef, columnDefs: columnDefsAdjusted, rowData: rowData, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, onModelUpdated: onModelUpdated, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, quickFilterParser: quickFilterParser, onSelectionChanged: synchroniseExternalStateToGridSelection, onColumnMoved: params.onColumnMoved, noRowsOverlayComponent: noRowsOverlayComponent, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, isExternalFilterPresent: isExternalFilterPresent, doesExternalFilterPass: doesExternalFilterPass, maintainColumnOrder: true, preventDefaultOnContextMenu: true, onCellContextMenu: gridContextMenu.cellContextMenu, rowDragText: params.rowDragText, onRowDragCancel: clearHighlightRowClasses, onRowDragMove: onRowDragMove, onRowDragEnd: onRowDragEnd, suppressCellFocus: params.suppressCellFocus, pinnedTopRowData: params.pinnedTopRowData, pinnedBottomRowData: params.pinnedBottomRowData, onRowClicked: params.onRowClicked, onRowDoubleClicked: params.onRowDoubleClicked, suppressStartEditOnTab: true }) })] }));
3976
+ : undefined, selectionColumnDef: selectionColumnDef, suppressCellFocus: params.suppressCellFocus, suppressClickEdit: true, suppressColumnVirtualisation: suppressColumnVirtualization, suppressStartEditOnTab: true }) })] }));
3474
3977
  };
3475
3978
  const quickFilterParser = (filterStr) => {
3476
3979
  // filter is exact matches exactly groups separated by commas
@@ -3711,33 +4214,6 @@ const GridFilterButtons = ({ className, luiButtonProps, options, }) => {
3711
4214
  return (jsxRuntime.jsx("div", { className: clsx(className, 'flex-col-center'), children: jsxRuntime.jsx(lui.LuiButtonGroup, { children: options.map((option, index) => (jsxRuntime.jsx(lui.LuiButton, { ...luiButtonProps, className: clsx(`lui-button lui-button-secondary`, selectedOption?.label === option.label && `lui-button-active`, luiButtonProps?.className), onClick: () => setSelectedOption(option), children: option.label }, `${index}`))) }) }));
3712
4215
  };
3713
4216
 
3714
- function styleInject(css, ref) {
3715
- if ( ref === void 0 ) ref = {};
3716
- var insertAt = ref.insertAt;
3717
-
3718
- if (!css || typeof document === 'undefined') { return; }
3719
-
3720
- var head = document.head || document.getElementsByTagName('head')[0];
3721
- var style = document.createElement('style');
3722
- style.type = 'text/css';
3723
-
3724
- if (insertAt === 'top') {
3725
- if (head.firstChild) {
3726
- head.insertBefore(style, head.firstChild);
3727
- } else {
3728
- head.appendChild(style);
3729
- }
3730
- } else {
3731
- head.appendChild(style);
3732
- }
3733
-
3734
- if (style.styleSheet) {
3735
- style.styleSheet.cssText = css;
3736
- } else {
3737
- style.appendChild(document.createTextNode(css));
3738
- }
3739
- }
3740
-
3741
4217
  var css_248z$3 = ".GridFilterColsMultiSelect{background:#fff;font-family:Open Sans,system-ui,sans-serif;font-style:normal;font-weight:600;padding:8px}.GridFilterColsMultiSelect .LuiSelect-label-text{color:#6b6966;display:inline-block}.GridFilterColsMultiSelect .LuiCheckboxInput-item,.GridFilterColsMultiSelect .LuiCheckboxInput-selectAll{color:#2a292c;font-size:16px;font-weight:600;letter-spacing:0;line-height:20px;line-height:24px;margin-bottom:0}";
3742
4218
  styleInject(css_248z$3);
3743
4219
 
@@ -4545,14 +5021,14 @@ const TextInputFormatted = (props) => {
4545
5021
 
4546
5022
  const bearingValueFormatter = (value) => {
4547
5023
  const safeValue = typeof value === 'string' ? parseFloat(value) : value;
4548
- if (safeValue == null) {
5024
+ if (safeValue == null || Number.isNaN(safeValue)) {
4549
5025
  return '–';
4550
5026
  }
4551
5027
  return convertDDToDMS(safeValue, false);
4552
5028
  };
4553
5029
  const bearingCorrectionValueFormatter = (value) => {
4554
5030
  const safeValue = value;
4555
- if (safeValue == null) {
5031
+ if (safeValue == null || Number.isNaN(safeValue)) {
4556
5032
  return '–';
4557
5033
  }
4558
5034
  if (typeof safeValue === 'string') {
@@ -5348,6 +5824,7 @@ const GridPopoutEditMultiSelectGrid = (colDef, props) => GridCell(colDef, {
5348
5824
  },
5349
5825
  });
5350
5826
 
5827
+ const GridCellBearingValueFormatter = (params) => bearingValueFormatter(params.value) ?? '';
5351
5828
  const GridPopoverEditBearingLike = (colDef, props) => GridCell({
5352
5829
  valueFormatter: (params) => props.editorParams?.formatValue(params.value) ?? '',
5353
5830
  ...colDef,
@@ -5500,6 +5977,7 @@ const GridContextProvider = (props) => {
5500
5977
  }
5501
5978
  return gridApi && !gridApi.isDestroyed() ? hasApiFn(gridApi) : noApiFn();
5502
5979
  }, [gridApi]);
5980
+ const getCellValue = React.useCallback((...props) => gridApi?.getCellValue(...props), [gridApi]);
5503
5981
  /**
5504
5982
  * Scroll row into view by Id.
5505
5983
  *
@@ -5659,7 +6137,7 @@ const GridContextProvider = (props) => {
5659
6137
  // It may be that the first cell is the selection cell, this doesn't exist as a colDef
5660
6138
  // so instead, I just try and select it. If it doesn't exist selection will stay on the
5661
6139
  // previously focused cell
5662
- gridApi.setFocusedCell(rowIndex, 'ag-Grid-SelectionColumn');
6140
+ gridApi.setFocusedCell(rowIndex, agGridSelectRowColId);
5663
6141
  }
5664
6142
  }, 100);
5665
6143
  }
@@ -6098,6 +6576,7 @@ const GridContextProvider = (props) => {
6098
6576
  getSelectedRowIds,
6099
6577
  getFilteredSelectedRowIds,
6100
6578
  getFirstRowId,
6579
+ getCellValue,
6101
6580
  editingCells,
6102
6581
  ensureRowVisible,
6103
6582
  ensureSelectedRowIsVisible,
@@ -6288,6 +6767,7 @@ exports.GenericCellEditorComponentWrapper = GenericCellEditorComponentWrapper;
6288
6767
  exports.Grid = Grid;
6289
6768
  exports.GridButton = GridButton;
6290
6769
  exports.GridCell = GridCell;
6770
+ exports.GridCellBearingValueFormatter = GridCellBearingValueFormatter;
6291
6771
  exports.GridCellFiller = GridCellFiller;
6292
6772
  exports.GridCellFillerColId = GridCellFillerColId;
6293
6773
  exports.GridCellMultiEditor = GridCellMultiEditor;
@@ -6351,6 +6831,7 @@ exports.SubMenu = SubMenu;
6351
6831
  exports.TextAreaInput = TextAreaInput;
6352
6832
  exports.TextInputFormatted = TextInputFormatted;
6353
6833
  exports.TextInputValidator = TextInputValidator;
6834
+ exports.agGridSelectRowColId = agGridSelectRowColId;
6354
6835
  exports.bearingCorrectionRangeValidator = bearingCorrectionRangeValidator;
6355
6836
  exports.bearingCorrectionValueFormatter = bearingCorrectionValueFormatter;
6356
6837
  exports.bearingNumberParser = bearingNumberParser;