@linzjs/step-ag-grid 1.5.2 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export * from "./src/contexts/GridContext";
6
6
  export * from "./src/contexts/GridContextProvider";
7
7
  export type { GridBaseRow } from "./src/components/Grid";
8
8
  export { Grid } from "./src/components/Grid";
9
- export { GridCell } from "./src/components/GridCell";
9
+ export * from "./src/components/GridCell";
10
10
  export { GridIcon } from "./src/components/GridIcon";
11
11
  export { ComponentLoadingWrapper } from "./src/components/ComponentLoadingWrapper";
12
12
  export { GenericMultiEditCellClass } from "./src/components/GenericCellClass";
@@ -24,13 +24,13 @@ export { GridPopoverMessage } from "./src/components/gridPopoverEdit/GridPopover
24
24
  export { GridPopoverTextArea } from "./src/components/gridPopoverEdit/GridPopoverTextArea";
25
25
  export { GridPopoverTextInput } from "./src/components/gridPopoverEdit/GridPopoverTextInput";
26
26
  export { GridHeaderSelect } from "./src/components/gridHeader/GridHeaderSelect";
27
- export { GridFormEditBearing } from "./src/components/gridForm/GridFormEditBearing";
28
- export { GridFormDropDown } from "./src/components/gridForm/GridFormDropDown";
29
- export { GridFormMessage } from "./src/components/gridForm/GridFormMessage";
30
- export { GridFormMultiSelect } from "./src/components/gridForm/GridFormMultiSelect";
31
- export { GridFormPopoutMenu } from "./src/components/gridForm/GridFormPopoutMenu";
32
- export { GridFormTextArea } from "./src/components/gridForm/GridFormTextArea";
33
- export { GridFormTextInput } from "./src/components/gridForm/GridFormTextInput";
27
+ export * from "./src/components/gridForm/GridFormEditBearing";
28
+ export * from "./src/components/gridForm/GridFormDropDown";
29
+ export * from "./src/components/gridForm/GridFormMessage";
30
+ export * from "./src/components/gridForm/GridFormMultiSelect";
31
+ export * from "./src/components/gridForm/GridFormPopoutMenu";
32
+ export * from "./src/components/gridForm/GridFormTextArea";
33
+ export * from "./src/components/gridForm/GridFormTextInput";
34
34
  export { TextAreaInput } from "./src/lui/TextAreaInput";
35
35
  export { TextInputFormatted } from "./src/lui/TextInputFormatted";
36
36
  export { GridSubComponentTextArea } from "./src/components/GridSubComponentTextArea";
package/dist/index.js CHANGED
@@ -1740,6 +1740,9 @@ var GridContext = react.createContext({
1740
1740
  ensureSelectedRowIsVisible: function () {
1741
1741
  console.error("no context provider for ensureSelectedRowIsVisible");
1742
1742
  },
1743
+ sizeColumnsToFit: function () {
1744
+ console.error("no context provider for sizeColumnsToFit");
1745
+ },
1743
1746
  editingCells: function () {
1744
1747
  console.error("no context provider for editingCells");
1745
1748
  return false;
@@ -1950,6 +1953,14 @@ var GridContextProvider = function (props) {
1950
1953
  gridApi.ensureNodeVisible(lodashEs.last(selectedNodes));
1951
1954
  });
1952
1955
  };
1956
+ /**
1957
+ * Resize columns to fit container
1958
+ */
1959
+ var sizeColumnsToFit = function () {
1960
+ gridApiOp(function (gridApi) {
1961
+ gridApi.sizeColumnsToFit();
1962
+ });
1963
+ };
1953
1964
  var stopEditing = function () { return gridApiOp(function (gridApi) { return gridApi.stopEditing(); }); };
1954
1965
  var updatingCells = function (props, fnUpdate, setSaving) { return __awaiter(void 0, void 0, void 0, function () {
1955
1966
  return __generator(this, function (_a) {
@@ -2016,6 +2027,7 @@ var GridContextProvider = function (props) {
2016
2027
  editingCells: editingCells,
2017
2028
  ensureRowVisible: ensureRowVisible,
2018
2029
  ensureSelectedRowIsVisible: ensureSelectedRowIsVisible,
2030
+ sizeColumnsToFit: sizeColumnsToFit,
2019
2031
  stopEditing: stopEditing,
2020
2032
  updatingCells: updatingCells
2021
2033
  } }, { children: props.children })));
@@ -2201,7 +2213,7 @@ var GridHeaderSelect = function (_a) {
2201
2213
  */
2202
2214
  var Grid = function (params) {
2203
2215
  var _a;
2204
- var _b = react.useContext(GridContext), gridReady = _b.gridReady, setGridApi = _b.setGridApi, setQuickFilter = _b.setQuickFilter, ensureRowVisible = _b.ensureRowVisible, selectRowsById = _b.selectRowsById, ensureSelectedRowIsVisible = _b.ensureSelectedRowIsVisible;
2216
+ var _b = react.useContext(GridContext), gridReady = _b.gridReady, setGridApi = _b.setGridApi, setQuickFilter = _b.setQuickFilter, ensureRowVisible = _b.ensureRowVisible, selectRowsById = _b.selectRowsById, ensureSelectedRowIsVisible = _b.ensureSelectedRowIsVisible, sizeColumnsToFit = _b.sizeColumnsToFit;
2205
2217
  var checkUpdating = react.useContext(UpdatingContext).checkUpdating;
2206
2218
  var _c = react.useState(""), internalQuickFilter = _c[0], setInternalQuickFilter = _c[1];
2207
2219
  var lastSelectedIds = react.useRef([]);
@@ -2300,14 +2312,6 @@ var Grid = function (params) {
2300
2312
  var _a;
2301
2313
  return (jsxRuntime.jsx("span", __assign({ className: "ag-overlay-no-rows-center" }, { children: (_a = params.noRowsOverlayText) !== null && _a !== void 0 ? _a : "There are currently no rows" })));
2302
2314
  }, [params.noRowsOverlayText]);
2303
- var sizeColumnsToFit = react.useCallback(function (event) {
2304
- // @ts-ignore (gridBodyCtrl is private)
2305
- if (event.api.gridBodyCtrl == undefined) {
2306
- return;
2307
- // this is here because ag grid was throwing api undefined error when closing POPPED OUT panel
2308
- }
2309
- event.api.sizeColumnsToFit();
2310
- }, []);
2311
2315
  var refreshSelectedRows = react.useCallback(function (event) {
2312
2316
  // Force-refresh all selected rows to re-run class function, to update selection highlighting
2313
2317
  event.api.refreshCells({
@@ -2353,6 +2357,12 @@ var Grid = function (params) {
2353
2357
  var cell = event.api.getFocusedCell();
2354
2358
  cell && event.api.setFocusedCell(cell.rowIndex, cell.column);
2355
2359
  }, [refreshSelectedRows]);
2360
+ // When rows added or removed then resize columns
2361
+ react.useEffect(function () {
2362
+ if (columnDefs === null || columnDefs === void 0 ? void 0 : columnDefs.length) {
2363
+ sizeColumnsToFit();
2364
+ }
2365
+ }, [columnDefs === null || columnDefs === void 0 ? void 0 : columnDefs.length, sizeColumnsToFit]);
2356
2366
  return (jsxRuntime.jsxs("div", __assign({ "data-testid": params.dataTestId, className: clsx("Grid-container", "ag-theme-alpine", staleGrid && "Grid-sortIsStale") }, { children: [params.quickFilter && (jsxRuntime.jsx("div", __assign({ className: "Grid-quickFilter" }, { children: jsxRuntime.jsx("input", { "aria-label": "Search", className: "lui-margin-top-xxs lui-margin-bottom-xxs Grid-quickFilterBox", type: "text", placeholder: (_a = params.quickFilterPlaceholder) !== null && _a !== void 0 ? _a : "Search...", value: internalQuickFilter, onChange: function (event) {
2357
2367
  setInternalQuickFilter(event.target.value);
2358
2368
  } }) }))), jsxRuntime.jsx(agGridReact.AgGridReact, { getRowId: function (params) { return "".concat(params.data.id); }, suppressRowClickSelection: true, rowSelection: "multiple", suppressBrowserResizeObserver: true, colResizeDefault: "shift", onFirstDataRendered: sizeColumnsToFit, onGridSizeChanged: sizeColumnsToFit, suppressClickEdit: true, onCellKeyDown: onCellKeyDown, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, onCellEditingStopped: onCellEditingStopped, domLayout: params.domLayout, columnDefs: columnDefs, rowData: params.rowData, noRowsOverlayComponent: noRowsOverlayComponent, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, postSortRows: postSortRows, onSelectionChanged: synchroniseExternalStateToGridSelection })] })));
@@ -2430,9 +2440,11 @@ var GridCell = function (props) {
2430
2440
  })), {
2431
2441
  // Default value formatter, otherwise react freaks out on objects
2432
2442
  valueFormatter: function (params) {
2433
- var types = ["number", "undefined", "boolean", "string"];
2443
+ if (params.value == null)
2444
+ return "-";
2445
+ var types = ["number", "boolean", "string"];
2434
2446
  if (types.includes(typeof params.value))
2435
- return params.value;
2447
+ return "".concat(params.value);
2436
2448
  else
2437
2449
  return JSON.stringify(params.value);
2438
2450
  } }), props), { cellRenderer: GridCellRenderer, cellRendererParams: __assign({ originalCellRenderer: props.cellRenderer }, props.cellRendererParams) });
@@ -2465,7 +2477,7 @@ var GenericCellEditorComponentFr = function (props, _) {
2465
2477
  }); }, [field, saving, selectedRows, updatingCells]);
2466
2478
  if (cellEditorParams == null)
2467
2479
  return jsxRuntime.jsx(jsxRuntime.Fragment, {});
2468
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { children: colDef.cellRenderer ? jsxRuntime.jsx(colDef.cellRenderer, __assign({}, props, { saving: saving })) : props.value }), (cellEditorParams === null || cellEditorParams === void 0 ? void 0 : cellEditorParams.form) && (jsxRuntime.jsx(cellEditorParams.form, { cellEditorParams: props, updateValue: updateValue, saving: saving, formProps: formProps, value: value, field: field, selectedRows: selectedRows }))] }));
2480
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { children: colDef.cellRenderer ? jsxRuntime.jsx(colDef.cellRenderer, __assign({}, props, { saving: saving })) : props.value }), (cellEditorParams === null || cellEditorParams === void 0 ? void 0 : cellEditorParams.form) && (jsxRuntime.jsx(cellEditorParams.form, { cellEditorParams: props, updateValue: updateValue, saving: saving, formProps: formProps, data: data, value: value, field: field, selectedRows: selectedRows }))] }));
2469
2481
  };
2470
2482
  var GenericCellEditorComponent = react.forwardRef(GenericCellEditorComponentFr);
2471
2483
 
@@ -2555,8 +2567,175 @@ var GridRenderPopoutMenuCell = function (props) {
2555
2567
  var css_248z$3 = "@charset \"UTF-8\";\n.szh-menu {\n margin: 0;\n padding: 0;\n list-style: none;\n box-sizing: border-box;\n width: max-content;\n z-index: 100;\n border: 1px solid rgba(0, 0, 0, 0.1);\n background-color: #fff;\n}\n.szh-menu:focus {\n outline: none;\n}\n.szh-menu__arrow {\n box-sizing: border-box;\n width: 0.75rem;\n height: 0.75rem;\n background-color: #fff;\n border: 1px solid transparent;\n border-left-color: rgba(0, 0, 0, 0.1);\n border-top-color: rgba(0, 0, 0, 0.1);\n z-index: -1;\n}\n.szh-menu__arrow--dir-left {\n right: -0.375rem;\n transform: translateY(-50%) rotate(135deg);\n}\n.szh-menu__arrow--dir-right {\n left: -0.375rem;\n transform: translateY(-50%) rotate(-45deg);\n}\n.szh-menu__arrow--dir-top {\n bottom: -0.375rem;\n transform: translateX(-50%) rotate(-135deg);\n}\n.szh-menu__arrow--dir-bottom {\n top: -0.375rem;\n transform: translateX(-50%) rotate(45deg);\n}\n.szh-menu__item {\n cursor: pointer;\n}\n.szh-menu__item:focus {\n outline: none;\n}\n.szh-menu__item--hover {\n background-color: #ebebeb;\n}\n.szh-menu__item--focusable {\n cursor: default;\n background-color: inherit;\n}\n.szh-menu__item--disabled {\n cursor: default;\n color: #aaa;\n}\n.szh-menu__group {\n box-sizing: border-box;\n}\n.szh-menu__radio-group {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n.szh-menu__divider {\n height: 1px;\n margin: 0.5rem 0;\n background-color: rgba(0, 0, 0, 0.12);\n}\n\n.szh-menu-button {\n box-sizing: border-box;\n}\n\n.szh-menu {\n user-select: none;\n color: #212529;\n border: none;\n border-radius: 0.25rem;\n box-shadow: 0 3px 7px rgba(0, 0, 0, 0.133), 0 0.6px 2px rgba(0, 0, 0, 0.1);\n min-width: 10rem;\n padding: 0.5rem 0;\n}\n.szh-menu__item {\n display: flex;\n align-items: center;\n position: relative;\n padding: 0.375rem 1.5rem;\n}\n.szh-menu-container--itemTransition .szh-menu__item {\n transition-property: background-color, color;\n transition-duration: 0.15s;\n transition-timing-function: ease-in-out;\n}\n.szh-menu__item--type-radio {\n padding-left: 2.2rem;\n}\n.szh-menu__item--type-radio::before {\n content: \"○\";\n position: absolute;\n left: 0.8rem;\n top: 0.55rem;\n font-size: 0.8rem;\n}\n.szh-menu__item--type-radio.szh-menu__item--checked::before {\n content: \"●\";\n}\n.szh-menu__item--type-checkbox {\n padding-left: 2.2rem;\n}\n.szh-menu__item--type-checkbox::before {\n position: absolute;\n left: 0.8rem;\n}\n.szh-menu__item--type-checkbox.szh-menu__item--checked::before {\n content: \"✔\";\n}\n.szh-menu__submenu > .szh-menu__item {\n padding-right: 2.5rem;\n}\n.szh-menu__submenu > .szh-menu__item::after {\n content: \"❯\";\n position: absolute;\n right: 1rem;\n}\n.szh-menu__header {\n color: #888;\n font-size: 0.8rem;\n padding: 0.2rem 1.5rem;\n text-transform: uppercase;\n}";
2556
2568
  styleInject(css_248z$3);
2557
2569
 
2558
- var MenuSeparatorString$1 = "_____MENU_SEPARATOR_____";
2559
- Object.freeze({ value: MenuSeparatorString$1 });
2570
+ var MenuSeparatorString = "_____MENU_SEPARATOR_____";
2571
+ var MenuSeparator = Object.freeze({ value: MenuSeparatorString });
2572
+ var GridFormDropDown = function (props) {
2573
+ var popoverWrapper = useGridPopoverHook(props).popoverWrapper;
2574
+ var formProps = props.formProps;
2575
+ var _a = react.useContext(GridContext), updatingCells = _a.updatingCells, stopEditing = _a.stopEditing;
2576
+ var _b = react.useState(""), filter = _b[0], setFilter = _b[1];
2577
+ var _c = react.useState([]), filteredValues = _c[0], setFilteredValues = _c[1];
2578
+ var optionsInitialising = react.useRef(false);
2579
+ var _d = react.useState(null), options = _d[0], setOptions = _d[1];
2580
+ var selectItemHandler = react.useCallback(function (value) { return __awaiter(void 0, void 0, void 0, function () {
2581
+ var field;
2582
+ return __generator(this, function (_a) {
2583
+ switch (_a.label) {
2584
+ case 0:
2585
+ field = props.field;
2586
+ return [4 /*yield*/, updatingCells({ selectedRows: props.selectedRows, field: field }, function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
2587
+ var hasChanged;
2588
+ return __generator(this, function (_a) {
2589
+ switch (_a.label) {
2590
+ case 0:
2591
+ hasChanged = selectedRows.some(function (row) { return row[field] !== value; });
2592
+ if (!hasChanged) return [3 /*break*/, 3];
2593
+ if (!formProps.onSelectedItem) return [3 /*break*/, 2];
2594
+ return [4 /*yield*/, formProps.onSelectedItem({ selectedRows: selectedRows, value: value })];
2595
+ case 1:
2596
+ _a.sent();
2597
+ return [3 /*break*/, 3];
2598
+ case 2:
2599
+ selectedRows.forEach(function (row) { return (row[field] = value); });
2600
+ _a.label = 3;
2601
+ case 3: return [2 /*return*/, true];
2602
+ }
2603
+ });
2604
+ }); })];
2605
+ case 1: return [2 /*return*/, _a.sent()];
2606
+ }
2607
+ });
2608
+ }); }, [formProps, props.field, props.selectedRows, updatingCells]);
2609
+ var selectFilterHandler = react.useCallback(function (value) { return __awaiter(void 0, void 0, void 0, function () {
2610
+ var field;
2611
+ return __generator(this, function (_a) {
2612
+ switch (_a.label) {
2613
+ case 0:
2614
+ field = props.field;
2615
+ return [4 /*yield*/, updatingCells({ selectedRows: props.selectedRows, field: field }, function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
2616
+ return __generator(this, function (_a) {
2617
+ switch (_a.label) {
2618
+ case 0:
2619
+ if (!formProps.onSelectFilter) return [3 /*break*/, 2];
2620
+ return [4 /*yield*/, formProps.onSelectFilter({ selectedRows: selectedRows, value: value })];
2621
+ case 1:
2622
+ _a.sent();
2623
+ _a.label = 2;
2624
+ case 2: return [2 /*return*/, true];
2625
+ }
2626
+ });
2627
+ }); })];
2628
+ case 1: return [2 /*return*/, _a.sent()];
2629
+ }
2630
+ });
2631
+ }); }, [formProps, props.field, props.selectedRows, updatingCells]);
2632
+ // Load up options list if it's async function
2633
+ react.useEffect(function () {
2634
+ var _a;
2635
+ if (options || optionsInitialising.current)
2636
+ return;
2637
+ optionsInitialising.current = true;
2638
+ var optionsConf = (_a = formProps.options) !== null && _a !== void 0 ? _a : [];
2639
+ (function () { return __awaiter(void 0, void 0, void 0, function () {
2640
+ var optionsList;
2641
+ return __generator(this, function (_a) {
2642
+ switch (_a.label) {
2643
+ case 0:
2644
+ if (!(typeof optionsConf == "function")) return [3 /*break*/, 2];
2645
+ return [4 /*yield*/, optionsConf(props.selectedRows, filter)];
2646
+ case 1:
2647
+ optionsConf = _a.sent();
2648
+ _a.label = 2;
2649
+ case 2:
2650
+ optionsList = optionsConf === null || optionsConf === void 0 ? void 0 : optionsConf.map(function (item) {
2651
+ if (item == null || typeof item == "string" || typeof item == "number") {
2652
+ item = { value: item, label: item, disabled: false };
2653
+ }
2654
+ return item;
2655
+ });
2656
+ if (formProps.filtered) {
2657
+ // This is needed otherwise when filter input is rendered and sets autofocus
2658
+ // the mouse up of the double click edit triggers the cell to cancel editing
2659
+ lodashEs.delay(function () { return setOptions(optionsList); }, 100);
2660
+ }
2661
+ else {
2662
+ setOptions(optionsList);
2663
+ }
2664
+ optionsInitialising.current = false;
2665
+ return [2 /*return*/];
2666
+ }
2667
+ });
2668
+ }); })();
2669
+ }, [filter, options, formProps.filtered, formProps.options, props.selectedRows]);
2670
+ // Local filtering
2671
+ react.useEffect(function () {
2672
+ if (formProps.filtered == "local") {
2673
+ if (options == null)
2674
+ return;
2675
+ setFilteredValues(options
2676
+ .map(function (option) {
2677
+ if (option.label != null && typeof option.label !== "string") {
2678
+ console.error("Cannot filter non-string labels", option);
2679
+ return undefined;
2680
+ }
2681
+ var str = option.label || "";
2682
+ return str.toLowerCase().indexOf(filter) === -1 ? option.value : undefined;
2683
+ })
2684
+ .filter(function (r) { return r !== undefined; }));
2685
+ }
2686
+ }, [formProps.filtered, filter, options]);
2687
+ var researchOnFilterChange = debounce__default["default"](react.useCallback(function () {
2688
+ setOptions(null);
2689
+ }, []), 500);
2690
+ var previousFilter = react.useRef(filter);
2691
+ // Reload filtering
2692
+ react.useEffect(function () {
2693
+ if (previousFilter.current != filter && formProps.filtered == "reload") {
2694
+ previousFilter.current = filter;
2695
+ formProps.optionsRequestCancel && formProps.optionsRequestCancel();
2696
+ researchOnFilterChange().then();
2697
+ }
2698
+ }, [filter, formProps, props, researchOnFilterChange]);
2699
+ var onFilterKeyDown = react.useCallback(function (e) { return __awaiter(void 0, void 0, void 0, function () {
2700
+ var activeOptions;
2701
+ return __generator(this, function (_a) {
2702
+ switch (_a.label) {
2703
+ case 0:
2704
+ if (!options)
2705
+ return [2 /*return*/];
2706
+ if (!(e.key == "Enter" || e.key == "Tab")) return [3 /*break*/, 5];
2707
+ activeOptions = options.filter(function (option) { return !filteredValues.includes(option.value); });
2708
+ if (!(activeOptions.length == 1)) return [3 /*break*/, 2];
2709
+ return [4 /*yield*/, selectItemHandler(activeOptions[0].value)];
2710
+ case 1:
2711
+ _a.sent();
2712
+ stopEditing();
2713
+ return [3 /*break*/, 5];
2714
+ case 2:
2715
+ if (!formProps.onSelectFilter) return [3 /*break*/, 4];
2716
+ return [4 /*yield*/, selectFilterHandler(filter)];
2717
+ case 3:
2718
+ _a.sent();
2719
+ stopEditing();
2720
+ return [3 /*break*/, 5];
2721
+ case 4:
2722
+ e.preventDefault();
2723
+ e.stopPropagation();
2724
+ _a.label = 5;
2725
+ case 5: return [2 /*return*/];
2726
+ }
2727
+ });
2728
+ }); }, [filteredValues, options, selectItemHandler, selectFilterHandler, stopEditing, filter, formProps]);
2729
+ return popoverWrapper(jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [formProps.filtered && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(FocusableItem, __assign({ className: "filter-item" }, { children: function (_a) {
2730
+ var _b;
2731
+ var ref = _a.ref;
2732
+ return (jsxRuntime.jsx("div", __assign({ style: { display: "flex", width: "100%" } }, { children: jsxRuntime.jsx("input", { autoFocus: true, className: "free-text-input", style: { border: "0px" }, ref: ref, type: "text", placeholder: (_b = formProps.filterPlaceholder) !== null && _b !== void 0 ? _b : "Placeholder", "data-testid": "filteredMenu-free-text-input", defaultValue: filter, onChange: function (e) { return setFilter(e.target.value.toLowerCase()); }, onKeyDown: function (e) { return onFilterKeyDown(e); } }) })));
2733
+ } })), jsxRuntime.jsx(MenuDivider, {}, "$$divider_filter")] })), jsxRuntime.jsx(ComponentLoadingWrapper, __assign({ loading: !options }, { children: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [options && options.length == (filteredValues === null || filteredValues === void 0 ? void 0 : filteredValues.length) && jsxRuntime.jsx(MenuItem, { children: "[Empty]" }), options === null || options === void 0 ? void 0 : options.map(function (item, index) {
2734
+ var _a;
2735
+ return item.value === MenuSeparatorString ? (jsxRuntime.jsx(MenuDivider, {}, "$$divider_".concat(index))) : filteredValues.includes(item.value) ? null : (jsxRuntime.jsx(MenuItem, __assign({ disabled: !!item.disabled, title: item.disabled && typeof item.disabled !== "boolean" ? item.disabled : "", value: item.value, onClick: function () { return selectItemHandler(item.value); } }, { children: (_a = item.label) !== null && _a !== void 0 ? _a : (item.value == null ? "<".concat(item.value, ">") : "".concat(item.value)) }), "".concat(props.field, "-").concat(index)));
2736
+ })] }) }))] }));
2737
+ };
2738
+
2560
2739
  var GridFormMultiSelect = function (props) {
2561
2740
  var formProps = props.formProps;
2562
2741
  var _a = react.useState(""), filter = _a[0], setFilter = _a[1];
@@ -2639,7 +2818,7 @@ var GridFormMultiSelect = function (props) {
2639
2818
  return (jsxRuntime.jsx("div", __assign({ style: { display: "flex", width: "100%" } }, { children: jsxRuntime.jsx("input", { autoFocus: true, className: "free-text-input", style: { border: "0px" }, ref: ref, type: "text", placeholder: (_b = formProps.filterPlaceholder) !== null && _b !== void 0 ? _b : "Placeholder", "data-testid": "filteredMenu-free-text-input", defaultValue: "", onChange: function (e) { return setFilter(e.target.value.toLowerCase()); } }) })));
2640
2819
  } }), "filter"), jsxRuntime.jsx(MenuDivider, {}, "$$divider_filter")] })), options === null || options === void 0 ? void 0 : options.map(function (item, index) {
2641
2820
  var _a;
2642
- return item.value === MenuSeparatorString$1 ? (jsxRuntime.jsx(MenuDivider, {}, "$$divider_".concat(index))) : filteredValues.includes(item.value) ? null : (jsxRuntime.jsxs(react.Fragment, { children: [jsxRuntime.jsx(MenuItem, __assign({ onClick: function (e) {
2821
+ return item.value === MenuSeparatorString ? (jsxRuntime.jsx(MenuDivider, {}, "$$divider_".concat(index))) : filteredValues.includes(item.value) ? null : (jsxRuntime.jsxs(react.Fragment, { children: [jsxRuntime.jsx(MenuItem, __assign({ onClick: function (e) {
2643
2822
  e.keepOpen = true;
2644
2823
  if (selectedValues.includes(item.value)) {
2645
2824
  setSelectedValues(selectedValues.filter(function (value) { return value != item.value; }));
@@ -2693,7 +2872,7 @@ var css_248z$2 = "/**\n @deprecated\n */\n/**\n @deprecated\n */\n/**\n @depr
2693
2872
  styleInject(css_248z$2);
2694
2873
 
2695
2874
  /** Menu configuration types **/
2696
- var MenuSeparator = Object.freeze({ __isMenuSeparator__: true });
2875
+ var PopoutMenuSeparator = Object.freeze({ __isMenuSeparator__: true });
2697
2876
  /**
2698
2877
  * NOTE: If the popout menu doesn't appear on single click when also selecting row it's because
2699
2878
  * you need a useMemo around your columnDefs
@@ -2756,11 +2935,11 @@ var GridFormPopoutMenu = function (props) {
2756
2935
  }); }, [props.field, props.selectedRows, updatingCells]);
2757
2936
  var selectedRowCount = props.selectedRows.length;
2758
2937
  var filteredOptions = options === null || options === void 0 ? void 0 : options.filter(function (menuOption) {
2759
- return menuOption.label === MenuSeparator || selectedRowCount === 1 || menuOption.supportsMultiEdit;
2938
+ return menuOption.label === PopoutMenuSeparator || selectedRowCount === 1 || menuOption.supportsMultiEdit;
2760
2939
  });
2761
2940
  var popoverWrapper = useGridPopoverHook(props).popoverWrapper;
2762
2941
  return popoverWrapper(jsxRuntime.jsx(ComponentLoadingWrapper, __assign({ loading: !filteredOptions }, { children: jsxRuntime.jsx("div", __assign({ className: "Grid-popoverContainerList" }, { children: options === null || options === void 0 ? void 0 : options.map(function (item, index) {
2763
- return item.label === MenuSeparator ? (jsxRuntime.jsx(MenuDivider, {}, "$$divider_".concat(index))) : (!item.hidden && (jsxRuntime.jsx(MenuItem, __assign({ onClick: function () { return actionClick(item); }, disabled: !!item.disabled || !(filteredOptions === null || filteredOptions === void 0 ? void 0 : filteredOptions.includes(item)), title: item.disabled && typeof item.disabled !== "boolean" ? item.disabled : "" }, { children: item.label }), "".concat(item.label))));
2942
+ return item.label === PopoutMenuSeparator ? (jsxRuntime.jsx(MenuDivider, {}, "$$divider_".concat(index))) : (!item.hidden && (jsxRuntime.jsx(MenuItem, __assign({ onClick: function () { return actionClick(item); }, disabled: !!item.disabled || !(filteredOptions === null || filteredOptions === void 0 ? void 0 : filteredOptions.includes(item)), title: item.disabled && typeof item.disabled !== "boolean" ? item.disabled : "" }, { children: item.label }), "".concat(item.label))));
2764
2943
  }) })) })));
2765
2944
  };
2766
2945
 
@@ -2862,7 +3041,7 @@ var css_248z = ".LuiTextInput {\n margin-bottom: 0;\n}\n\n.LuiTextInput-formatt
2862
3041
  styleInject(css_248z);
2863
3042
 
2864
3043
  var TextInputFormatted = function (props) {
2865
- return (jsxRuntime.jsxs("div", __assign({ className: clsx("LuiTextInput Grid-popoverContainer", props.error && "hasError", props.warning && "hasWarning", props.className) }, { children: [jsxRuntime.jsxs("span", __assign({ className: "LuiTextInput-inputWrapper" }, { children: [jsxRuntime.jsx("input", __assign({ type: "text", className: "LuiTextInput-input", min: "0", value: props.value, onChange: props.onChange }, props.inputProps)), jsxRuntime.jsx("span", __assign({ className: "LuiTextInput-formatted" }, { children: props.formatted })), props.icon] })), props.error && (jsxRuntime.jsxs("span", __assign({ className: "LuiTextInput-error" }, { children: [jsxRuntime.jsx(lui.LuiIcon, { alt: "error", name: "ic_error", className: "LuiTextInput-error-icon", size: "sm", status: "error" }), props.error] }))), props.warning && (jsxRuntime.jsxs("span", __assign({ className: "LuiTextInput-warning" }, { children: [jsxRuntime.jsx(lui.LuiIcon, { alt: "warning", name: "ic_warning", className: "LuiTextInput-warning-icon", size: "sm", status: "warning" }), props.warning] })))] })));
3044
+ return (jsxRuntime.jsxs("div", __assign({ className: clsx("LuiTextInput Grid-popoverContainer", props.error && "hasError", props.warning && "hasWarning", props.className) }, { children: [jsxRuntime.jsxs("span", __assign({ className: "LuiTextInput-inputWrapper" }, { children: [jsxRuntime.jsx("input", __assign({ type: "text", className: "LuiTextInput-input", min: "0", value: props.value, onChange: props.onChange }, props.inputProps)), jsxRuntime.jsx("span", __assign({ className: "LuiTextInput-formatted" }, { children: props.formatted }))] })), props.error && (jsxRuntime.jsxs("span", __assign({ className: "LuiTextInput-error" }, { children: [jsxRuntime.jsx(lui.LuiIcon, { alt: "error", name: "ic_error", className: "LuiTextInput-error-icon", size: "sm", status: "error" }), props.error] }))), props.warning && (jsxRuntime.jsxs("span", __assign({ className: "LuiTextInput-warning" }, { children: [jsxRuntime.jsx(lui.LuiIcon, { alt: "warning", name: "ic_warning", className: "LuiTextInput-warning-icon", size: "sm", status: "warning" }), props.warning] })))] })));
2866
3045
  };
2867
3046
 
2868
3047
  var GridFormEditBearing = function (props) {
@@ -2942,175 +3121,6 @@ var GridPopoverEditBearingCorrection = function (colDef) {
2942
3121
  } }, init.cellEditorParams) });
2943
3122
  };
2944
3123
 
2945
- var MenuSeparatorString = "_____MENU_SEPARATOR_____";
2946
- Object.freeze({ value: MenuSeparatorString });
2947
- var GridFormDropDown = function (props) {
2948
- var popoverWrapper = useGridPopoverHook(props).popoverWrapper;
2949
- var formProps = props.formProps;
2950
- var _a = react.useContext(GridContext), updatingCells = _a.updatingCells, stopEditing = _a.stopEditing;
2951
- var _b = react.useState(""), filter = _b[0], setFilter = _b[1];
2952
- var _c = react.useState([]), filteredValues = _c[0], setFilteredValues = _c[1];
2953
- var optionsInitialising = react.useRef(false);
2954
- var _d = react.useState(null), options = _d[0], setOptions = _d[1];
2955
- var selectItemHandler = react.useCallback(function (value) { return __awaiter(void 0, void 0, void 0, function () {
2956
- var field;
2957
- return __generator(this, function (_a) {
2958
- switch (_a.label) {
2959
- case 0:
2960
- field = props.field;
2961
- return [4 /*yield*/, updatingCells({ selectedRows: props.selectedRows, field: field }, function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
2962
- var hasChanged;
2963
- return __generator(this, function (_a) {
2964
- switch (_a.label) {
2965
- case 0:
2966
- hasChanged = selectedRows.some(function (row) { return row[field] !== value; });
2967
- if (!hasChanged) return [3 /*break*/, 3];
2968
- if (!formProps.onSelectedItem) return [3 /*break*/, 2];
2969
- return [4 /*yield*/, formProps.onSelectedItem({ selectedRows: selectedRows, value: value })];
2970
- case 1:
2971
- _a.sent();
2972
- return [3 /*break*/, 3];
2973
- case 2:
2974
- selectedRows.forEach(function (row) { return (row[field] = value); });
2975
- _a.label = 3;
2976
- case 3: return [2 /*return*/, true];
2977
- }
2978
- });
2979
- }); })];
2980
- case 1: return [2 /*return*/, _a.sent()];
2981
- }
2982
- });
2983
- }); }, [formProps, props.field, props.selectedRows, updatingCells]);
2984
- var selectFilterHandler = react.useCallback(function (value) { return __awaiter(void 0, void 0, void 0, function () {
2985
- var field;
2986
- return __generator(this, function (_a) {
2987
- switch (_a.label) {
2988
- case 0:
2989
- field = props.field;
2990
- return [4 /*yield*/, updatingCells({ selectedRows: props.selectedRows, field: field }, function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
2991
- return __generator(this, function (_a) {
2992
- switch (_a.label) {
2993
- case 0:
2994
- if (!formProps.onSelectFilter) return [3 /*break*/, 2];
2995
- return [4 /*yield*/, formProps.onSelectFilter({ selectedRows: selectedRows, value: value })];
2996
- case 1:
2997
- _a.sent();
2998
- _a.label = 2;
2999
- case 2: return [2 /*return*/, true];
3000
- }
3001
- });
3002
- }); })];
3003
- case 1: return [2 /*return*/, _a.sent()];
3004
- }
3005
- });
3006
- }); }, [formProps, props.field, props.selectedRows, updatingCells]);
3007
- // Load up options list if it's async function
3008
- react.useEffect(function () {
3009
- var _a;
3010
- if (options || optionsInitialising.current)
3011
- return;
3012
- optionsInitialising.current = true;
3013
- var optionsConf = (_a = formProps.options) !== null && _a !== void 0 ? _a : [];
3014
- (function () { return __awaiter(void 0, void 0, void 0, function () {
3015
- var optionsList;
3016
- return __generator(this, function (_a) {
3017
- switch (_a.label) {
3018
- case 0:
3019
- if (!(typeof optionsConf == "function")) return [3 /*break*/, 2];
3020
- return [4 /*yield*/, optionsConf(props.selectedRows, filter)];
3021
- case 1:
3022
- optionsConf = _a.sent();
3023
- _a.label = 2;
3024
- case 2:
3025
- optionsList = optionsConf === null || optionsConf === void 0 ? void 0 : optionsConf.map(function (item) {
3026
- if (item == null || typeof item == "string" || typeof item == "number") {
3027
- item = { value: item, label: item, disabled: false };
3028
- }
3029
- return item;
3030
- });
3031
- if (formProps.filtered) {
3032
- // This is needed otherwise when filter input is rendered and sets autofocus
3033
- // the mouse up of the double click edit triggers the cell to cancel editing
3034
- lodashEs.delay(function () { return setOptions(optionsList); }, 100);
3035
- }
3036
- else {
3037
- setOptions(optionsList);
3038
- }
3039
- optionsInitialising.current = false;
3040
- return [2 /*return*/];
3041
- }
3042
- });
3043
- }); })();
3044
- }, [filter, options, formProps.filtered, formProps.options, props.selectedRows]);
3045
- // Local filtering
3046
- react.useEffect(function () {
3047
- if (formProps.filtered == "local") {
3048
- if (options == null)
3049
- return;
3050
- setFilteredValues(options
3051
- .map(function (option) {
3052
- if (option.label != null && typeof option.label !== "string") {
3053
- console.error("Cannot filter non-string labels", option);
3054
- return undefined;
3055
- }
3056
- var str = option.label || "";
3057
- return str.toLowerCase().indexOf(filter) === -1 ? option.value : undefined;
3058
- })
3059
- .filter(function (r) { return r !== undefined; }));
3060
- }
3061
- }, [formProps.filtered, filter, options]);
3062
- var researchOnFilterChange = debounce__default["default"](react.useCallback(function () {
3063
- setOptions(null);
3064
- }, []), 500);
3065
- var previousFilter = react.useRef(filter);
3066
- // Reload filtering
3067
- react.useEffect(function () {
3068
- if (previousFilter.current != filter && formProps.filtered == "reload") {
3069
- previousFilter.current = filter;
3070
- formProps.optionsRequestCancel && formProps.optionsRequestCancel();
3071
- researchOnFilterChange().then();
3072
- }
3073
- }, [filter, formProps, props, researchOnFilterChange]);
3074
- var onFilterKeyDown = react.useCallback(function (e) { return __awaiter(void 0, void 0, void 0, function () {
3075
- var activeOptions;
3076
- return __generator(this, function (_a) {
3077
- switch (_a.label) {
3078
- case 0:
3079
- if (!options)
3080
- return [2 /*return*/];
3081
- if (!(e.key == "Enter" || e.key == "Tab")) return [3 /*break*/, 5];
3082
- activeOptions = options.filter(function (option) { return !filteredValues.includes(option.value); });
3083
- if (!(activeOptions.length == 1)) return [3 /*break*/, 2];
3084
- return [4 /*yield*/, selectItemHandler(activeOptions[0].value)];
3085
- case 1:
3086
- _a.sent();
3087
- stopEditing();
3088
- return [3 /*break*/, 5];
3089
- case 2:
3090
- if (!formProps.onSelectFilter) return [3 /*break*/, 4];
3091
- return [4 /*yield*/, selectFilterHandler(filter)];
3092
- case 3:
3093
- _a.sent();
3094
- stopEditing();
3095
- return [3 /*break*/, 5];
3096
- case 4:
3097
- e.preventDefault();
3098
- e.stopPropagation();
3099
- _a.label = 5;
3100
- case 5: return [2 /*return*/];
3101
- }
3102
- });
3103
- }); }, [filteredValues, options, selectItemHandler, selectFilterHandler, stopEditing, filter, formProps]);
3104
- return popoverWrapper(jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [formProps.filtered && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(FocusableItem, __assign({ className: "filter-item" }, { children: function (_a) {
3105
- var _b;
3106
- var ref = _a.ref;
3107
- return (jsxRuntime.jsx("div", __assign({ style: { display: "flex", width: "100%" } }, { children: jsxRuntime.jsx("input", { autoFocus: true, className: "free-text-input", style: { border: "0px" }, ref: ref, type: "text", placeholder: (_b = formProps.filterPlaceholder) !== null && _b !== void 0 ? _b : "Placeholder", "data-testid": "filteredMenu-free-text-input", defaultValue: filter, onChange: function (e) { return setFilter(e.target.value.toLowerCase()); }, onKeyDown: function (e) { return onFilterKeyDown(e); } }) })));
3108
- } })), jsxRuntime.jsx(MenuDivider, {}, "$$divider_filter")] })), jsxRuntime.jsx(ComponentLoadingWrapper, __assign({ loading: !options }, { children: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [options && options.length == (filteredValues === null || filteredValues === void 0 ? void 0 : filteredValues.length) && jsxRuntime.jsx(MenuItem, { children: "[Empty]" }), options === null || options === void 0 ? void 0 : options.map(function (item, index) {
3109
- var _a;
3110
- return item.value === MenuSeparatorString ? (jsxRuntime.jsx(MenuDivider, {}, "$$divider_".concat(index))) : filteredValues.includes(item.value) ? null : (jsxRuntime.jsx(MenuItem, __assign({ disabled: !!item.disabled, title: item.disabled && typeof item.disabled !== "boolean" ? item.disabled : "", value: item.value, onClick: function () { return selectItemHandler(item.value); } }, { children: (_a = item.label) !== null && _a !== void 0 ? _a : (item.value == null ? "<".concat(item.value, ">") : "".concat(item.value)) }), "".concat(props.field, "-").concat(index)));
3111
- })] }) }))] }));
3112
- };
3113
-
3114
3124
  var GridPopoverEditDropDown = function (colDef) {
3115
3125
  var _a;
3116
3126
  return GridCell(__assign(__assign({ initialWidth: 65, maxWidth: 150, cellClass: ((_a = colDef.cellEditor) === null || _a === void 0 ? void 0 : _a.multiEdit) ? GenericMultiEditCellClass : undefined }, colDef), ((colDef === null || colDef === void 0 ? void 0 : colDef.cellEditorParams) && {
@@ -3209,32 +3219,35 @@ var GridPopoverTextArea = function (colDef) {
3209
3219
  };
3210
3220
 
3211
3221
  var GridFormTextInput = function (props) {
3212
- var _a, _b;
3222
+ var _a;
3213
3223
  var formProps = props.formProps;
3214
- var _c = react.useState((_a = props.value) !== null && _a !== void 0 ? _a : ""), value = _c[0], setValue = _c[1];
3224
+ var initValue = props.value == null ? "" : "".concat(props.value);
3225
+ var _b = react.useState(initValue), value = _b[0], setValue = _b[1];
3215
3226
  var invalid = react.useCallback(function () {
3216
- if (formProps.required && value.length == 0) {
3227
+ var trimmedValue = value.trim();
3228
+ if (formProps.required && trimmedValue.length == 0) {
3217
3229
  return "Some text is required";
3218
3230
  }
3219
- if (formProps.maxlength && value.length > formProps.maxlength) {
3231
+ if (formProps.maxlength && trimmedValue.length > formProps.maxlength) {
3220
3232
  return "Text must be no longer than ".concat(formProps.maxlength, " characters");
3221
3233
  }
3222
3234
  if (formProps.validate) {
3223
- return formProps.validate(value);
3235
+ return formProps.validate(trimmedValue, props.data);
3224
3236
  }
3225
3237
  return null;
3226
3238
  }, [formProps, value]);
3227
3239
  var save = react.useCallback(function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
3228
- var field;
3240
+ var trimmedValue, field;
3229
3241
  return __generator(this, function (_a) {
3230
3242
  switch (_a.label) {
3231
3243
  case 0:
3232
3244
  if (invalid())
3233
3245
  return [2 /*return*/, false];
3234
- if (props.value === (value !== null && value !== void 0 ? value : ""))
3246
+ trimmedValue = value.trim();
3247
+ if (initValue === trimmedValue)
3235
3248
  return [2 /*return*/, true];
3236
3249
  if (!formProps.onSave) return [3 /*break*/, 2];
3237
- return [4 /*yield*/, formProps.onSave(selectedRows, value)];
3250
+ return [4 /*yield*/, formProps.onSave(selectedRows, trimmedValue)];
3238
3251
  case 1: return [2 /*return*/, _a.sent()];
3239
3252
  case 2:
3240
3253
  field = props.field;
@@ -3242,13 +3255,13 @@ var GridFormTextInput = function (props) {
3242
3255
  console.error("ColDef has no field set");
3243
3256
  return [2 /*return*/, false];
3244
3257
  }
3245
- selectedRows.forEach(function (row) { return (row[field] = value); });
3258
+ selectedRows.forEach(function (row) { return (row[field] = trimmedValue); });
3246
3259
  return [2 /*return*/, true];
3247
3260
  }
3248
3261
  });
3249
- }); }, [invalid, props.value, props.field, value, formProps]);
3250
- var _d = useGridPopoverHook(props, save), popoverWrapper = _d.popoverWrapper, triggerSave = _d.triggerSave;
3251
- return popoverWrapper(jsxRuntime.jsx("div", __assign({ style: { display: "flex", flexDirection: "row", width: (_b = formProps.width) !== null && _b !== void 0 ? _b : 240 }, className: "FormTest" }, { children: jsxRuntime.jsx(TextInputFormatted, { value: value, onChange: function (e) { return setValue(e.target.value); }, error: invalid(), formatted: "", inputProps: {
3262
+ }); }, [invalid, value, initValue, formProps, props.field]);
3263
+ var _c = useGridPopoverHook(props, save), popoverWrapper = _c.popoverWrapper, triggerSave = _c.triggerSave;
3264
+ return popoverWrapper(jsxRuntime.jsx("div", __assign({ style: { display: "flex", flexDirection: "row", width: (_a = formProps.width) !== null && _a !== void 0 ? _a : 240 }, className: "FormTest" }, { children: jsxRuntime.jsx(TextInputFormatted, { value: value, onChange: function (e) { return setValue(e.target.value); }, error: invalid(), formatted: formProps.units, inputProps: {
3252
3265
  style: { width: "100%" },
3253
3266
  placeholder: formProps.placeholder,
3254
3267
  onKeyDown: function (e) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
@@ -3274,9 +3287,12 @@ var GridSubComponentTextArea = function (props) {
3274
3287
  exports.ComponentLoadingWrapper = ComponentLoadingWrapper;
3275
3288
  exports.ControlledMenu = ControlledMenu;
3276
3289
  exports.FocusableItem = FocusableItem;
3290
+ exports.GenericCellEditorComponent = GenericCellEditorComponent;
3291
+ exports.GenericCellEditorComponentFr = GenericCellEditorComponentFr;
3277
3292
  exports.GenericMultiEditCellClass = GenericMultiEditCellClass;
3278
3293
  exports.Grid = Grid;
3279
3294
  exports.GridCell = GridCell;
3295
+ exports.GridCellRenderer = GridCellRenderer;
3280
3296
  exports.GridContext = GridContext;
3281
3297
  exports.GridContextProvider = GridContextProvider;
3282
3298
  exports.GridFormDropDown = GridFormDropDown;
@@ -3307,6 +3323,9 @@ exports.MenuGroup = MenuGroup;
3307
3323
  exports.MenuHeader = MenuHeader;
3308
3324
  exports.MenuItem = MenuItem;
3309
3325
  exports.MenuRadioGroup = MenuRadioGroup;
3326
+ exports.MenuSeparator = MenuSeparator;
3327
+ exports.MenuSeparatorString = MenuSeparatorString;
3328
+ exports.PopoutMenuSeparator = PopoutMenuSeparator;
3310
3329
  exports.SubMenu = SubMenu;
3311
3330
  exports.TextAreaInput = TextAreaInput;
3312
3331
  exports.TextInputFormatted = TextInputFormatted;