@linzjs/step-ag-grid 4.0.2 → 5.0.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 (49) hide show
  1. package/dist/index.js +325 -265
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/components/GridPopoverHook.d.ts +2 -13
  4. package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -1
  5. package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +1 -1
  6. package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +0 -1
  7. package/dist/src/contexts/GridContext.d.ts +1 -0
  8. package/dist/src/contexts/GridPopoverContext.d.ts +1 -1
  9. package/dist/src/contexts/GridUpdatingContext.d.ts +3 -2
  10. package/dist/src/contexts/GridUpdatingContextProvider.d.ts +1 -1
  11. package/dist/src/lui/FormError.d.ts +6 -0
  12. package/dist/src/react-menu3/components/MenuItem.d.ts +1 -1
  13. package/dist/src/react-menu3/components/SubMenu.d.ts +1 -1
  14. package/dist/src/react-menu3/hooks/useBEM.d.ts +1 -1
  15. package/dist/src/react-menu3/types.d.ts +18 -17
  16. package/dist/src/react-menu3/utils/constants.d.ts +4 -0
  17. package/dist/src/react-menu3/utils/utils.d.ts +1 -1
  18. package/dist/step-ag-grid.esm.js +326 -266
  19. package/dist/step-ag-grid.esm.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/components/GridPopoverHook.tsx +30 -79
  22. package/src/components/gridForm/GridFormDropDown.tsx +62 -46
  23. package/src/components/gridForm/GridFormEditBearing.tsx +16 -8
  24. package/src/components/gridForm/GridFormMultiSelect.tsx +12 -4
  25. package/src/components/gridForm/GridFormPopoverMenu.tsx +25 -22
  26. package/src/components/gridForm/GridFormSubComponentTextArea.tsx +1 -14
  27. package/src/components/gridForm/GridFormSubComponentTextInput.tsx +1 -18
  28. package/src/components/gridForm/GridFormTextArea.tsx +8 -5
  29. package/src/components/gridForm/GridFormTextInput.tsx +8 -4
  30. package/src/contexts/GridContext.tsx +4 -0
  31. package/src/contexts/GridContextProvider.tsx +8 -0
  32. package/src/contexts/GridPopoverContext.tsx +1 -1
  33. package/src/contexts/GridPopoverContextProvider.tsx +7 -4
  34. package/src/contexts/GridUpdatingContext.tsx +7 -1
  35. package/src/contexts/GridUpdatingContextProvider.tsx +17 -6
  36. package/src/lui/FormError.tsx +29 -0
  37. package/src/lui/TextAreaInput.tsx +2 -18
  38. package/src/lui/TextInputFormatted.tsx +2 -17
  39. package/src/react-menu3/components/ControlledMenu.tsx +114 -12
  40. package/src/react-menu3/components/MenuItem.tsx +19 -2
  41. package/src/react-menu3/types.ts +2 -0
  42. package/src/react-menu3/utils/constants.ts +4 -0
  43. package/src/stories/grid/FormTest.tsx +24 -21
  44. package/src/stories/grid/GridPopoutBearing.stories.tsx +3 -2
  45. package/src/stories/grid/GridPopoutEditDropDown.stories.tsx +10 -0
  46. package/src/stories/grid/GridPopoutEditMultiSelect.stories.tsx +1 -1
  47. package/src/stories/grid/GridReadOnly.stories.tsx +11 -11
  48. package/src/styles/GridFormDropDown.scss +1 -1
  49. package/src/utils/bearing.ts +1 -1
@@ -1,6 +1,6 @@
1
1
  import { useMemo, useLayoutEffect, useEffect, createContext, memo, forwardRef, useRef, useContext, useState, useCallback, useReducer, cloneElement, useImperativeHandle, Fragment } from 'react';
2
2
  import { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
3
- import { findIndex, debounce, isEmpty, delay, sortBy, last, difference, castArray, remove, flatten, xorBy, fromPairs, omit, pick, toPairs, isEqual } from 'lodash-es';
3
+ import { findIndex, debounce, isEmpty, delay, sortBy, last, difference, castArray, remove, flatten, xorBy, fromPairs, pick, omit, toPairs, isEqual } from 'lodash-es';
4
4
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
5
5
  import { AgGridReact } from 'ag-grid-react';
6
6
  import { LuiMiniSpinner, LuiIcon, LuiCheckboxInput, LuiButton } from '@linzjs/lui';
@@ -69,6 +69,7 @@ var subMenuClass = "submenu";
69
69
  var radioGroupClass = "radio-group";
70
70
  var Keys = Object.freeze({
71
71
  ENTER: "Enter",
72
+ TAB: "Tab",
72
73
  ESC: "Escape",
73
74
  SPACE: " ",
74
75
  HOME: "Home",
@@ -92,7 +93,9 @@ var CloseReason = Object.freeze({
92
93
  CLICK: "click",
93
94
  CANCEL: "cancel",
94
95
  BLUR: "blur",
95
- SCROLL: "scroll"
96
+ SCROLL: "scroll",
97
+ TAB_FORWARD: "tab_forward",
98
+ TAB_BACKWARD: "tab_backward"
96
99
  });
97
100
  var FocusPositions = Object.freeze({
98
101
  FIRST: "first",
@@ -1364,14 +1367,120 @@ var ControlledMenuFr = function (_a, externalRef) {
1364
1367
  ev.stopPropagation();
1365
1368
  }
1366
1369
  }, [isWithinMenu]);
1370
+ var lastTabDownEl = useRef();
1371
+ var lastEnterDownEl = useRef();
1372
+ var handleKeyboardTabAndEnter = useCallback(function (isDown) { return function (ev) {
1373
+ var thisDocument = (anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current) ? anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current.ownerDocument : document;
1374
+ var activeElement = thisDocument.activeElement;
1375
+ if (!(anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current) || !activeElement)
1376
+ return;
1377
+ if (ev.key !== "Tab" && ev.key !== "Enter")
1378
+ return;
1379
+ if (ev.repeat) {
1380
+ ev.preventDefault();
1381
+ ev.stopPropagation();
1382
+ return;
1383
+ }
1384
+ var inputElsIterator = thisDocument.querySelectorAll(".szh-menu--state-open input,textarea");
1385
+ var inputEls = [];
1386
+ inputElsIterator.forEach(function (el) { return inputEls.push(el); });
1387
+ inputEls = inputEls.filter(function (el) { return !el.disabled; });
1388
+ if (inputEls.length === 0)
1389
+ return;
1390
+ var firstInputEl = inputEls[0];
1391
+ var lastInputEl = inputEls[inputEls.length - 1];
1392
+ if (activeElement !== firstInputEl && activeElement !== lastInputEl)
1393
+ return;
1394
+ var suppressAutoSaveEvents = activeElement.getAttribute("data-suppressAutoSaveEvents");
1395
+ var invokeSave = function (reason) {
1396
+ var _a, _b;
1397
+ if (!(saveButtonRef === null || saveButtonRef === void 0 ? void 0 : saveButtonRef.current) || suppressAutoSaveEvents)
1398
+ return;
1399
+ (_a = saveButtonRef.current) === null || _a === void 0 ? void 0 : _a.setAttribute("data-reason", reason);
1400
+ (_b = saveButtonRef === null || saveButtonRef === void 0 ? void 0 : saveButtonRef.current) === null || _b === void 0 ? void 0 : _b.click();
1401
+ };
1402
+ var isTextArea = activeElement.nodeName === "TEXTAREA";
1403
+ switch (activeElement.nodeName) {
1404
+ case "TEXTAREA":
1405
+ case "INPUT": {
1406
+ if (activeElement === lastInputEl && activeElement === firstInputEl) {
1407
+ if (ev.key === "Tab") {
1408
+ // Can't forward/backwards tab out of popup
1409
+ ev.preventDefault();
1410
+ ev.stopPropagation();
1411
+ if (isDown) {
1412
+ lastTabDownEl.current = activeElement;
1413
+ }
1414
+ else {
1415
+ lastTabDownEl.current == activeElement &&
1416
+ invokeSave(ev.shiftKey ? CloseReason.TAB_BACKWARD : CloseReason.TAB_FORWARD);
1417
+ }
1418
+ }
1419
+ if (ev.key === "Enter" && !isTextArea) {
1420
+ ev.preventDefault();
1421
+ ev.stopPropagation();
1422
+ if (isDown) {
1423
+ lastEnterDownEl.current = activeElement;
1424
+ }
1425
+ else {
1426
+ lastEnterDownEl.current == activeElement && invokeSave(CloseReason.CLICK);
1427
+ }
1428
+ }
1429
+ }
1430
+ else if (activeElement === lastInputEl) {
1431
+ if (ev.key === "Tab" && !ev.shiftKey) {
1432
+ // Can't backward tab out of popup
1433
+ ev.preventDefault();
1434
+ ev.stopPropagation();
1435
+ if (isDown) {
1436
+ lastTabDownEl.current = activeElement;
1437
+ }
1438
+ else {
1439
+ lastTabDownEl.current == activeElement && invokeSave(CloseReason.TAB_FORWARD);
1440
+ }
1441
+ }
1442
+ if (ev.key === "Enter" && !isTextArea) {
1443
+ ev.preventDefault();
1444
+ ev.stopPropagation();
1445
+ if (isDown) {
1446
+ lastEnterDownEl.current = activeElement;
1447
+ }
1448
+ else {
1449
+ lastEnterDownEl.current == activeElement && invokeSave(CloseReason.CLICK);
1450
+ }
1451
+ }
1452
+ }
1453
+ else if (activeElement === firstInputEl) {
1454
+ if (ev.key === "Tab" && ev.shiftKey) {
1455
+ // Can't backward tab out of popup
1456
+ ev.preventDefault();
1457
+ ev.stopPropagation();
1458
+ if (isDown) {
1459
+ lastTabDownEl.current = activeElement;
1460
+ }
1461
+ else {
1462
+ lastTabDownEl.current == activeElement && invokeSave(CloseReason.TAB_BACKWARD);
1463
+ }
1464
+ }
1465
+ }
1466
+ break;
1467
+ }
1468
+ }
1469
+ }; }, [anchorRef, saveButtonRef]);
1470
+ var handleKeydownTabAndEnter = useMemo(function () { return handleKeyboardTabAndEnter(true); }, [handleKeyboardTabAndEnter]);
1471
+ var handleKeyupTabAndEnter = useMemo(function () { return handleKeyboardTabAndEnter(false); }, [handleKeyboardTabAndEnter]);
1367
1472
  useEffect(function () {
1368
1473
  if (isMenuOpen(state)) {
1369
1474
  var thisDocument_1 = (anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current) ? anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current.ownerDocument : document;
1475
+ thisDocument_1.addEventListener("keydown", handleKeydownTabAndEnter, true);
1476
+ thisDocument_1.addEventListener("keyup", handleKeyupTabAndEnter, true);
1370
1477
  thisDocument_1.addEventListener("mousedown", handleScreenEventForSave, true);
1371
1478
  thisDocument_1.addEventListener("mouseup", handleScreenEventForCancel, true);
1372
1479
  thisDocument_1.addEventListener("click", handleScreenEventForCancel, true);
1373
1480
  thisDocument_1.addEventListener("dblclick", handleScreenEventForCancel, true);
1374
1481
  return function () {
1482
+ thisDocument_1.addEventListener("keydown", handleKeydownTabAndEnter, true);
1483
+ thisDocument_1.addEventListener("keyup", handleKeyupTabAndEnter, true);
1375
1484
  thisDocument_1.removeEventListener("mousedown", handleScreenEventForSave, true);
1376
1485
  thisDocument_1.removeEventListener("mouseup", handleScreenEventForCancel, true);
1377
1486
  thisDocument_1.removeEventListener("click", handleScreenEventForCancel, true);
@@ -1379,7 +1488,14 @@ var ControlledMenuFr = function (_a, externalRef) {
1379
1488
  };
1380
1489
  }
1381
1490
  return function () { };
1382
- }, [handleScreenEventForSave, handleScreenEventForCancel, state, anchorRef]);
1491
+ }, [
1492
+ handleScreenEventForSave,
1493
+ handleScreenEventForCancel,
1494
+ state,
1495
+ anchorRef,
1496
+ handleKeydownTabAndEnter,
1497
+ handleKeyupTabAndEnter,
1498
+ ]);
1383
1499
  var itemSettings = useMemo(function () { return ({
1384
1500
  submenuOpenDelay: submenuOpenDelay,
1385
1501
  submenuCloseDelay: submenuCloseDelay
@@ -1674,8 +1790,11 @@ var MenuItemFr = function (_a) {
1674
1790
  value: value,
1675
1791
  syntheticEvent: e
1676
1792
  };
1677
- if (e.key !== undefined)
1678
- event.key = e.key;
1793
+ if (e.key !== undefined) {
1794
+ var ke = e;
1795
+ event.key = ke.key;
1796
+ event.shiftKey = ke.shiftKey;
1797
+ }
1679
1798
  if (isCheckBox)
1680
1799
  event.checked = !isChecked;
1681
1800
  if (isRadio)
@@ -1685,6 +1804,13 @@ var MenuItemFr = function (_a) {
1685
1804
  safeCall(radioGroup.onRadioChange, event);
1686
1805
  eventHandlers.handleClick(event, isCheckBox || isRadio);
1687
1806
  };
1807
+ var handleKeyDown = function (e) {
1808
+ // if tab is allowed the handleKeyUp event can't process the tab
1809
+ if (e.key === "Tab") {
1810
+ e.preventDefault();
1811
+ e.stopPropagation();
1812
+ }
1813
+ };
1688
1814
  /**
1689
1815
  * Keyboard events are triggered on up, otherwise sub-components get spaces and enters typed in them
1690
1816
  */
@@ -1693,7 +1819,10 @@ var MenuItemFr = function (_a) {
1693
1819
  return;
1694
1820
  switch (e.key) {
1695
1821
  case Keys.ENTER:
1822
+ case Keys.TAB:
1696
1823
  case Keys.SPACE:
1824
+ e.preventDefault();
1825
+ e.stopPropagation();
1697
1826
  if (isAnchor) {
1698
1827
  (menuItemRef === null || menuItemRef === void 0 ? void 0 : menuItemRef.current) && menuItemRef.current.click();
1699
1828
  }
@@ -1710,7 +1839,7 @@ var MenuItemFr = function (_a) {
1710
1839
  checked: isChecked,
1711
1840
  anchor: isAnchor
1712
1841
  }); }, [type, isDisabled, isHovering, isChecked, isAnchor]);
1713
- var mergedProps = mergeProps(__assign(__assign({}, restStateProps), { onPointerDown: setHover, onKeyUp: handleKeyUp, onClick: handleClick }), restProps);
1842
+ var mergedProps = mergeProps(__assign(__assign({}, restStateProps), { onPointerDown: setHover, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onClick: handleClick }), restProps);
1714
1843
  // Order of props overriding (same in all components):
1715
1844
  // 1. Preset props adhering to WAI-ARIA Authoring Practices.
1716
1845
  // 2. Merged outer and local props
@@ -1855,6 +1984,9 @@ var GridContext = createContext({
1855
1984
  }); },
1856
1985
  redrawRows: function () {
1857
1986
  console.error("no context provider for redrawRows");
1987
+ },
1988
+ selectNextCell: function () {
1989
+ console.error("no context provider for selectNextCell");
1858
1990
  }
1859
1991
  });
1860
1992
 
@@ -1868,7 +2000,8 @@ var GridUpdatingContext = createContext({
1868
2000
  console.error("Missing GridUpdatingContext");
1869
2001
  return [2 /*return*/];
1870
2002
  });
1871
- }); }
2003
+ }); },
2004
+ updatedDep: 0
1872
2005
  });
1873
2006
 
1874
2007
  /**
@@ -2128,6 +2261,15 @@ var GridContextProvider = function (props) {
2128
2261
  gridApi.redrawRows(rowNodes ? { rowNodes: rowNodes } : undefined);
2129
2262
  });
2130
2263
  };
2264
+ var selectNextCell = function (tabDirection) {
2265
+ if (tabDirection === void 0) { tabDirection = 0; }
2266
+ gridApiOp(function (gridApi) {
2267
+ if (tabDirection == 1)
2268
+ gridApi.tabToNextCell();
2269
+ if (tabDirection == -1)
2270
+ gridApi.tabToPreviousCell();
2271
+ });
2272
+ };
2131
2273
  return (jsx(GridContext.Provider, __assign({ value: {
2132
2274
  gridReady: gridReady,
2133
2275
  setGridApi: setGridApi,
@@ -2146,34 +2288,42 @@ var GridContextProvider = function (props) {
2146
2288
  sizeColumnsToFit: sizeColumnsToFit,
2147
2289
  stopEditing: stopEditing,
2148
2290
  updatingCells: updatingCells,
2149
- redrawRows: redrawRows
2291
+ redrawRows: redrawRows,
2292
+ selectNextCell: selectNextCell
2150
2293
  } }, { children: props.children })));
2151
2294
  };
2152
2295
 
2153
2296
  var GridUpdatingContextProvider = function (props) {
2154
2297
  var updatingBlocks = useRef({});
2155
2298
  var updating = useRef({});
2299
+ var _a = useState(0), updatedDep = _a[0], setUpdatedDep = _a[1];
2156
2300
  var resetUpdating = function () {
2157
2301
  var mergedUpdatingBlocks = {};
2158
2302
  for (var key in updatingBlocks.current) {
2159
2303
  mergedUpdatingBlocks[key] = flatten(updatingBlocks.current[key]);
2160
2304
  }
2161
2305
  updating.current = mergedUpdatingBlocks;
2306
+ setUpdatedDep(function (updatedDep) { return updatedDep + 1; });
2162
2307
  };
2163
- var modifyUpdating = function (field, ids, fn) { return __awaiter(void 0, void 0, void 0, function () {
2164
- var fieldUpdatingIds, idRef;
2165
- var _a;
2166
- return __generator(this, function (_b) {
2167
- switch (_b.label) {
2308
+ var modifyUpdating = function (fields, ids, fn) { return __awaiter(void 0, void 0, void 0, function () {
2309
+ var idRef;
2310
+ return __generator(this, function (_a) {
2311
+ switch (_a.label) {
2168
2312
  case 0:
2169
- fieldUpdatingIds = (_a = updatingBlocks.current[field]) !== null && _a !== void 0 ? _a : (updatingBlocks.current[field] = []);
2170
2313
  idRef = __spreadArray([], ids, true);
2171
- fieldUpdatingIds.push(idRef);
2314
+ castArray(fields).forEach(function (field) {
2315
+ var _a;
2316
+ var fieldUpdatingIds = (_a = updatingBlocks.current[field]) !== null && _a !== void 0 ? _a : (updatingBlocks.current[field] = []);
2317
+ fieldUpdatingIds.push(idRef);
2318
+ });
2172
2319
  resetUpdating();
2173
2320
  return [4 /*yield*/, fn()];
2174
2321
  case 1:
2175
- _b.sent();
2176
- remove(fieldUpdatingIds, function (idList) { return idList === idRef; });
2322
+ _a.sent();
2323
+ castArray(fields).forEach(function (field) {
2324
+ var fieldUpdatingIds = updatingBlocks.current[field];
2325
+ remove(fieldUpdatingIds, function (idList) { return idList === idRef; });
2326
+ });
2177
2327
  resetUpdating();
2178
2328
  return [2 /*return*/];
2179
2329
  }
@@ -2182,7 +2332,7 @@ var GridUpdatingContextProvider = function (props) {
2182
2332
  var checkUpdating = function (fields, id) {
2183
2333
  return castArray(fields).some(function (f) { var _a; return (_a = updating.current[f]) === null || _a === void 0 ? void 0 : _a.includes(id); });
2184
2334
  };
2185
- return (jsx(GridUpdatingContext.Provider, __assign({ value: { modifyUpdating: modifyUpdating, checkUpdating: checkUpdating } }, { children: props.children })));
2335
+ return (jsx(GridUpdatingContext.Provider, __assign({ value: { modifyUpdating: modifyUpdating, checkUpdating: checkUpdating, updatedDep: updatedDep } }, { children: props.children })));
2186
2336
  };
2187
2337
 
2188
2338
  var GridPopoverContext = createContext({
@@ -2204,7 +2354,7 @@ var useGridPopoverContext = function () {
2204
2354
  var GridPopoverContextProvider = function (_a) {
2205
2355
  var _b, _c, _d;
2206
2356
  var props = _a.props, children = _a.children;
2207
- var _e = useContext(GridContext), getSelectedRows = _e.getSelectedRows, updatingCells = _e.updatingCells, stopEditing = _e.stopEditing;
2357
+ var _e = useContext(GridContext), getSelectedRows = _e.getSelectedRows, updatingCells = _e.updatingCells, stopEditing = _e.stopEditing, selectNextCell = _e.selectNextCell;
2208
2358
  var anchorRef = useRef(props.eGridCell);
2209
2359
  var _f = useState(false), saving = _f[0], setSaving = _f[1];
2210
2360
  var colDef = props.colDef;
@@ -2213,7 +2363,7 @@ var GridPopoverContextProvider = function (_a) {
2213
2363
  // Then item that is clicked on will always be first in the list
2214
2364
  var selectedRows = useMemo(function () { return (multiEdit ? sortBy(getSelectedRows(), function (row) { return row.id !== props.data.id; }) : [props.data]); }, [getSelectedRows, multiEdit, props.data]);
2215
2365
  var field = (_d = (_c = props.colDef) === null || _c === void 0 ? void 0 : _c.field) !== null && _d !== void 0 ? _d : "";
2216
- var updateValue = useCallback(function (saveFn) { return __awaiter(void 0, void 0, void 0, function () {
2366
+ var updateValue = useCallback(function (saveFn, tabDirection) { return __awaiter(void 0, void 0, void 0, function () {
2217
2367
  var result;
2218
2368
  return __generator(this, function (_a) {
2219
2369
  switch (_a.label) {
@@ -2223,13 +2373,15 @@ var GridPopoverContextProvider = function (_a) {
2223
2373
  return [4 /*yield*/, updatingCells({ selectedRows: selectedRows, field: field }, saveFn, setSaving)];
2224
2374
  case 1:
2225
2375
  result = _a.sent();
2226
- if (result)
2376
+ if (result) {
2227
2377
  stopEditing();
2378
+ tabDirection && selectNextCell(tabDirection);
2379
+ }
2228
2380
  _a.label = 2;
2229
2381
  case 2: return [2 /*return*/, result];
2230
2382
  }
2231
2383
  });
2232
- }); }, [field, saving, selectedRows, stopEditing, updatingCells]);
2384
+ }); }, [field, saving, selectNextCell, selectedRows, stopEditing, updatingCells]);
2233
2385
  return (jsx(GridPopoverContext.Provider, __assign({ value: {
2234
2386
  anchorRef: anchorRef,
2235
2387
  saving: saving,
@@ -2259,43 +2411,7 @@ var GridSubComponentContext = createContext({
2259
2411
  }); }
2260
2412
  });
2261
2413
 
2262
- function toVal(mix) {
2263
- var k, y, str='';
2264
- if (mix) {
2265
- if (typeof mix === 'object') {
2266
- if (Array.isArray(mix)) {
2267
- for (k=0; k < mix.length; k++) {
2268
- if (mix[k] && (y = toVal(mix[k]))) {
2269
- str && (str += ' ');
2270
- str += y;
2271
- }
2272
- }
2273
- } else {
2274
- for (k in mix) {
2275
- if (mix[k] && (y = toVal(k))) {
2276
- str && (str += ' ');
2277
- str += y;
2278
- }
2279
- }
2280
- }
2281
- } else if (typeof mix !== 'boolean' && !mix.call) {
2282
- str && (str += ' ');
2283
- str += mix;
2284
- }
2285
- }
2286
- return str;
2287
- }
2288
-
2289
- function clsx () {
2290
- var i=0, x, str='';
2291
- while (i < arguments.length) {
2292
- if (x = toVal(arguments[i++])) {
2293
- str && (str += ' ');
2294
- str += x;
2295
- }
2296
- }
2297
- return str;
2298
- }
2414
+ function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);else for(t in e)e[t]&&(n&&(n+=" "),n+=t);return n}function clsx(){for(var e,t,f=0,n="";f<arguments.length;)(e=arguments[f++])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
2299
2415
 
2300
2416
  /**
2301
2417
  * Retains last sort order from via <AgGrid postRowSort>.
@@ -2794,96 +2910,35 @@ var useGridPopoverHook = function (props) {
2794
2910
  setOpen(true);
2795
2911
  }, []);
2796
2912
  var triggerSave = useCallback(function (reason) { return __awaiter(void 0, void 0, void 0, function () {
2797
- var _a, _b;
2798
- return __generator(this, function (_c) {
2799
- switch (_c.label) {
2913
+ return __generator(this, function (_a) {
2914
+ switch (_a.label) {
2800
2915
  case 0:
2801
- _a = reason == "cancel" || !props.save;
2802
- if (_a) return [3 /*break*/, 3];
2803
- _b = updateValue;
2804
- if (!_b) return [3 /*break*/, 2];
2805
- return [4 /*yield*/, updateValue(props.save)];
2916
+ if (reason == "cancel") {
2917
+ stopEditing();
2918
+ return [2 /*return*/];
2919
+ }
2920
+ if (props.invalid && props.invalid()) {
2921
+ return [2 /*return*/];
2922
+ }
2923
+ if (!!props.save) return [3 /*break*/, 1];
2924
+ stopEditing();
2925
+ return [3 /*break*/, 3];
2806
2926
  case 1:
2807
- _b = (_c.sent());
2808
- _c.label = 2;
2809
- case 2:
2810
- _a = (_b);
2811
- _c.label = 3;
2812
- case 3:
2813
- if (_a) {
2814
- setOpen(false);
2927
+ if (!props.save) return [3 /*break*/, 3];
2928
+ // forms that don't provide an invalid fn must wait until they have saved to close
2929
+ if (props.invalid)
2815
2930
  stopEditing();
2931
+ return [4 /*yield*/, updateValue(props.save, reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)];
2932
+ case 2:
2933
+ if (_a.sent()) {
2934
+ if (!props.invalid)
2935
+ stopEditing();
2816
2936
  }
2817
- return [2 /*return*/];
2937
+ _a.label = 3;
2938
+ case 3: return [2 /*return*/];
2818
2939
  }
2819
2940
  });
2820
- }); }, [props.save, stopEditing, updateValue]);
2821
- var onlyInputKeyboardEventHandlers = {
2822
- onKeyUp: function (e) {
2823
- var isTextArea = e.currentTarget.type === "textarea";
2824
- if (e.key === "Enter" && !isTextArea) {
2825
- e.preventDefault();
2826
- e.stopPropagation();
2827
- triggerSave().then();
2828
- }
2829
- else if (e.key === "Tab") {
2830
- e.preventDefault();
2831
- e.stopPropagation();
2832
- }
2833
- },
2834
- onKeyDown: function (e) {
2835
- var isTextArea = e.currentTarget.type === "textarea";
2836
- if (e.key === "Enter" && !isTextArea) {
2837
- e.preventDefault();
2838
- e.stopPropagation();
2839
- }
2840
- else if (e.key === "Tab") {
2841
- e.preventDefault();
2842
- e.stopPropagation();
2843
- !e.shiftKey && triggerSave().then();
2844
- }
2845
- }
2846
- };
2847
- var firstInputKeyboardEventHandlers = {
2848
- onKeyUp: function (e) {
2849
- if (e.key === "Tab" && e.shiftKey) {
2850
- e.preventDefault();
2851
- e.stopPropagation();
2852
- }
2853
- },
2854
- onKeyDown: function (e) {
2855
- if (e.key === "Tab" && e.shiftKey) {
2856
- e.preventDefault();
2857
- e.stopPropagation();
2858
- }
2859
- }
2860
- };
2861
- var lastInputKeyboardEventHandlers = {
2862
- onKeyUp: function (e) {
2863
- var isTextArea = e.currentTarget.type === "textarea";
2864
- if (e.key === "Enter" && !isTextArea) {
2865
- e.preventDefault();
2866
- e.stopPropagation();
2867
- triggerSave().then();
2868
- }
2869
- else if (e.key === "Tab" && !e.shiftKey) {
2870
- e.preventDefault();
2871
- e.stopPropagation();
2872
- }
2873
- },
2874
- onKeyDown: function (e) {
2875
- var isTextArea = e.currentTarget.type === "textarea";
2876
- if (e.key === "Enter" && !isTextArea) {
2877
- e.preventDefault();
2878
- e.stopPropagation();
2879
- }
2880
- else if (e.key === "Tab" && !e.shiftKey) {
2881
- e.preventDefault();
2882
- e.stopPropagation();
2883
- triggerSave().then();
2884
- }
2885
- }
2886
- };
2941
+ }); }, [props, stopEditing, updateValue]);
2887
2942
  var popoverWrapper = useCallback(function (children) {
2888
2943
  return (jsx(Fragment$1, { children: anchorRef.current && (jsxs(ControlledMenu, __assign({ state: isOpen ? "open" : "closed", portal: true, unmountOnClose: true, anchorRef: anchorRef, saveButtonRef: saveButtonRef, menuClassName: "step-ag-grid-react-menu", onClose: function (event) {
2889
2944
  // Prevent menu from closing when modals are invoked
@@ -2899,14 +2954,14 @@ var useGridPopoverHook = function (props) {
2899
2954
  right: 0,
2900
2955
  backgroundColor: "rgba(64,64,64,0.1)",
2901
2956
  zIndex: 1000
2902
- } })), children, jsx("button", { ref: saveButtonRef, onClick: function () { return triggerSave().then(); }, style: { display: "none" } })] }))) }));
2957
+ } })), children, jsx("button", { ref: saveButtonRef, "data-reason": "", onClick: function (e) {
2958
+ var _a;
2959
+ triggerSave((_a = e.currentTarget.getAttribute("data-reason")) !== null && _a !== void 0 ? _a : undefined).then();
2960
+ }, style: { display: "none" } })] }))) }));
2903
2961
  }, [anchorRef, isOpen, props.className, saving, triggerSave]);
2904
2962
  return {
2905
2963
  popoverWrapper: popoverWrapper,
2906
- triggerSave: triggerSave,
2907
- onlyInputKeyboardEventHandlers: onlyInputKeyboardEventHandlers,
2908
- firstInputKeyboardEventHandlers: firstInputKeyboardEventHandlers,
2909
- lastInputKeyboardEventHandlers: lastInputKeyboardEventHandlers
2964
+ triggerSave: triggerSave
2910
2965
  };
2911
2966
  };
2912
2967
 
@@ -2932,7 +2987,7 @@ var GridRenderPopoutMenuCell = function (props) {
2932
2987
  var css_248z$5 = ".GridMultiSelect-containerSmall .GridFormMultiSelect-options{max-height:130px;overflow-y:auto}.GridMultiSelect-containerMedium .GridFormMultiSelect-options{max-height:190px;overflow-y:auto}.GridMultiSelect-containerLarge .GridFormMultiSelect-options{max-height:320px;overflow-y:auto}.GridMultiSelect-containerUnlimited .GridFormMultiSelect-options{overflow-y:auto}";
2933
2988
  styleInject(css_248z$5);
2934
2989
 
2935
- var css_248z$4 = ".GridPopoverEditDropDown-containerSmall .GridFormDropDown-options{max-height:120px;overflow-y:auto}.GridPopoverEditDropDown-containerMedium .GridFormDropDown-options{max-height:200px;overflow-y:auto}.GridPopoverEditDropDown-containerLarge .GridFormDropDown-options{max-height:400px;overflow-y:auto}.GridPopoverEditDropDown-containerUnlimited .GridFormDropDown-options{overflow-y:auto}";
2990
+ var css_248z$4 = ".GridPopoverEditDropDown-containerSmall .GridFormDropDown-options{max-height:120px;overflow-y:auto}.GridPopoverEditDropDown-containerMedium .GridFormDropDown-options{max-height:220px;overflow-y:auto}.GridPopoverEditDropDown-containerLarge .GridFormDropDown-options{max-height:400px;overflow-y:auto}.GridPopoverEditDropDown-containerUnlimited .GridFormDropDown-options{overflow-y:auto}";
2936
2991
  styleInject(css_248z$4);
2937
2992
 
2938
2993
  /* global setTimeout, clearTimeout */
@@ -3017,18 +3072,20 @@ var fieldToString = function (field) {
3017
3072
  };
3018
3073
  var GridFormDropDown = function (props) {
3019
3074
  var _a = useGridPopoverContext(), selectedRows = _a.selectedRows, field = _a.field, updateValue = _a.updateValue, data = _a.data;
3020
- var stopEditing = useContext(GridContext).stopEditing;
3075
+ // Save triggers during async action processing which triggers another selectItem(), this ref blocks that
3076
+ var hasSubmitted = useRef(false);
3021
3077
  var _b = useState(""), filter = _b[0], setFilter = _b[1];
3022
3078
  var _c = useState([]), filteredValues = _c[0], setFilteredValues = _c[1];
3023
3079
  var optionsInitialising = useRef(false);
3024
3080
  var _d = useState(null), options = _d[0], setOptions = _d[1];
3025
3081
  var subComponentIsValid = useRef(false);
3026
3082
  var _e = useState(), subSelectedValue = _e[0], setSubSelectedValue = _e[1];
3027
- var _f = useState(), selectedSubComponent = _f[0], setSelectedSubComponent = _f[1];
3028
- var selectItemHandler = useCallback(function (value, subComponentValue) { return __awaiter(void 0, void 0, void 0, function () {
3083
+ var _f = useState(null), selectedSubComponent = _f[0], setSelectedSubComponent = _f[1];
3084
+ var selectItemHandler = useCallback(function (value, subComponentValue, reason) { return __awaiter(void 0, void 0, void 0, function () {
3029
3085
  return __generator(this, function (_a) {
3030
- if (subComponentValue !== undefined && !subComponentIsValid.current)
3086
+ if (hasSubmitted.current || (subComponentValue !== undefined && !subComponentIsValid.current))
3031
3087
  return [2 /*return*/, false];
3088
+ hasSubmitted.current = true;
3032
3089
  return [2 /*return*/, updateValue(function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
3033
3090
  var hasChanged;
3034
3091
  return __generator(this, function (_a) {
@@ -3047,7 +3104,7 @@ var GridFormDropDown = function (props) {
3047
3104
  case 3: return [2 /*return*/, true];
3048
3105
  }
3049
3106
  });
3050
- }); })];
3107
+ }); }, reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)];
3051
3108
  });
3052
3109
  }); }, [field, props, updateValue]);
3053
3110
  var selectFilterHandler = useCallback(function (value) { return __awaiter(void 0, void 0, void 0, function () {
@@ -3067,7 +3124,7 @@ var GridFormDropDown = function (props) {
3067
3124
  return [2 /*return*/, true];
3068
3125
  }
3069
3126
  });
3070
- }); })];
3127
+ }); }, 0)];
3071
3128
  });
3072
3129
  }); }, [props, updateValue]);
3073
3130
  // Load up options list if it's async function
@@ -3141,74 +3198,80 @@ var GridFormDropDown = function (props) {
3141
3198
  researchOnFilterChange().then();
3142
3199
  }
3143
3200
  }, [filter, props, researchOnFilterChange]);
3144
- var onFilterKeyDown = useCallback(function (e) { return __awaiter(void 0, void 0, void 0, function () {
3201
+ var save = useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
3145
3202
  var activeOptions;
3146
3203
  return __generator(this, function (_a) {
3147
3204
  switch (_a.label) {
3148
3205
  case 0:
3149
3206
  if (!options)
3150
- return [2 /*return*/];
3151
- if (!(e.key == "Enter" || e.key == "Tab")) return [3 /*break*/, 5];
3207
+ return [2 /*return*/, true];
3152
3208
  activeOptions = options.filter(function (option) { return !filteredValues.includes(option.value); });
3153
- if (!(activeOptions.length == 1)) return [3 /*break*/, 2];
3209
+ if (!(activeOptions.length === 1)) return [3 /*break*/, 2];
3154
3210
  return [4 /*yield*/, selectItemHandler(activeOptions[0].value)];
3155
3211
  case 1:
3156
3212
  _a.sent();
3157
- stopEditing();
3158
- return [3 /*break*/, 5];
3213
+ return [3 /*break*/, 6];
3159
3214
  case 2:
3160
- if (!props.onSelectFilter) return [3 /*break*/, 4];
3215
+ if (!(activeOptions.length === 0 && props.onSelectFilter)) return [3 /*break*/, 4];
3161
3216
  return [4 /*yield*/, selectFilterHandler(filter)];
3162
3217
  case 3:
3163
3218
  _a.sent();
3164
- stopEditing();
3165
- return [3 /*break*/, 5];
3219
+ return [3 /*break*/, 6];
3166
3220
  case 4:
3167
- e.preventDefault();
3168
- e.stopPropagation();
3169
- _a.label = 5;
3170
- case 5: return [2 /*return*/];
3171
- }
3172
- });
3173
- }); }, [filteredValues, options, selectItemHandler, selectFilterHandler, stopEditing, filter, props]);
3174
- var save = useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
3175
- return __generator(this, function (_a) {
3176
- switch (_a.label) {
3177
- case 0:
3178
3221
  // Handler for sub-selected value
3179
3222
  if (!selectedSubComponent)
3180
3223
  return [2 /*return*/, true];
3181
- if (!subComponentIsValid.current)
3224
+ if (selectedSubComponent.subComponent && !subComponentIsValid.current)
3182
3225
  return [2 /*return*/, false];
3183
3226
  return [4 /*yield*/, selectItemHandler(selectedSubComponent.value, subSelectedValue)];
3184
- case 1:
3227
+ case 5:
3185
3228
  _a.sent();
3186
- return [2 /*return*/, true];
3229
+ _a.label = 6;
3230
+ case 6: return [2 /*return*/, true];
3187
3231
  }
3188
3232
  });
3189
- }); }, [selectItemHandler, selectedSubComponent, subSelectedValue]);
3190
- var popoverWrapper = useGridPopoverHook({ className: props.className, save: save }).popoverWrapper;
3233
+ }); }, [
3234
+ filter,
3235
+ filteredValues,
3236
+ options,
3237
+ props.onSelectFilter,
3238
+ selectFilterHandler,
3239
+ selectItemHandler,
3240
+ selectedSubComponent,
3241
+ subSelectedValue,
3242
+ ]);
3243
+ var popoverWrapper = useGridPopoverHook({
3244
+ className: props.className,
3245
+ invalid: function () { return !!(selectedSubComponent && !subComponentIsValid.current); },
3246
+ save: save
3247
+ }).popoverWrapper;
3191
3248
  return popoverWrapper(jsxs(Fragment$1, { children: [props.filtered && (jsxs("div", __assign({ className: "GridFormDropDown-filter" }, { children: [jsx(FocusableItem, __assign({ className: "filter-item" }, { children: function (_a) {
3192
3249
  var _b;
3193
3250
  var ref = _a.ref;
3194
- return (jsx("div", __assign({ style: { display: "flex", width: "100%" } }, { children: jsx("input", { autoFocus: true, className: "free-text-input", style: { border: "0px" }, ref: ref, type: "text", placeholder: (_b = props.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); } }) })));
3251
+ return (jsx("div", __assign({ style: { display: "flex", width: "100%" } }, { children: jsx("input", { autoFocus: true, className: "free-text-input", style: { border: "0px" }, ref: ref, type: "text", placeholder: (_b = props.filterPlaceholder) !== null && _b !== void 0 ? _b : "Placeholder", "data-testid": "filteredMenu-free-text-input", defaultValue: filter, onChange: function (e) { return setFilter(e.target.value.toLowerCase()); } }) })));
3195
3252
  } })), jsx(MenuDivider, {}, "$$divider_filter")] }))), jsx(ComponentLoadingWrapper, __assign({ loading: !options, className: "GridFormDropDown-options" }, { children: jsxs(Fragment$1, { children: [options && options.length == (filteredValues === null || filteredValues === void 0 ? void 0 : filteredValues.length) && (jsx(MenuItem, { children: "[Empty]" }, "".concat(fieldToString(field), "-empty"))), options === null || options === void 0 ? void 0 : options.map(function (item, index) {
3196
3253
  var _a;
3197
- return item.value === MenuSeparatorString ? (jsx(MenuDivider, {}, "$$divider_".concat(index))) : item.value === MenuHeaderString ? (jsx(MenuHeader, { children: item.label }, "$$header_".concat(index))) : filteredValues.includes(item.value) ? null : (jsxs("div", { children: [jsx(MenuItem, __assign({ disabled: !!item.disabled, title: item.disabled && typeof item.disabled !== "boolean" ? item.disabled : "", value: item.value, onClick: function (e) {
3254
+ return item.value === MenuSeparatorString ? (jsx(MenuDivider, {}, "$$divider_".concat(index))) : item.value === MenuHeaderString ? (jsx(MenuHeader, { children: item.label }, "$$header_".concat(index))) : filteredValues.includes(item.value) ? null : (jsxs("div", { children: [jsxs(MenuItem, __assign({ disabled: !!item.disabled, title: item.disabled && typeof item.disabled !== "boolean" ? item.disabled : "", value: item.value, onClick: function (e) {
3198
3255
  if (item.subComponent) {
3199
3256
  if (selectedSubComponent === item) {
3257
+ // toggle selection off
3200
3258
  setSelectedSubComponent(null);
3201
3259
  subComponentIsValid.current = true;
3202
3260
  }
3203
3261
  else {
3262
+ // toggle selection on
3204
3263
  setSelectedSubComponent(item);
3205
3264
  }
3206
3265
  e.keepOpen = true;
3207
3266
  }
3208
3267
  else {
3209
- selectItemHandler(item.value).then();
3268
+ selectItemHandler(item.value, undefined, e.key === "Tab"
3269
+ ? e.shiftKey
3270
+ ? CloseReason.TAB_BACKWARD
3271
+ : CloseReason.TAB_FORWARD
3272
+ : CloseReason.CLICK).then();
3210
3273
  }
3211
- } }, { children: (_a = item.label) !== null && _a !== void 0 ? _a : (item.value == null ? "<".concat(item.value, ">") : "".concat(item.value)) }), "".concat(fieldToString(field), "-").concat(index)), item.subComponent && selectedSubComponent === item && (jsx(FocusableItem, __assign({ className: "LuiDeprecatedForms" }, { children: function (ref) { return (jsx(GridSubComponentContext.Provider, __assign({ value: {
3274
+ } }, { children: [(_a = item.label) !== null && _a !== void 0 ? _a : (item.value == null ? "<".concat(item.value, ">") : "".concat(item.value)), item.subComponent ? "..." : ""] }), "".concat(fieldToString(field), "-").concat(index)), item.subComponent && selectedSubComponent === item && (jsx(FocusableItem, __assign({ className: "LuiDeprecatedForms" }, { children: function (ref) { return (jsx(GridSubComponentContext.Provider, __assign({ value: {
3212
3275
  data: data,
3213
3276
  value: subSelectedValue,
3214
3277
  setValue: function (value) {
@@ -3240,6 +3303,10 @@ var GridFormMultiSelect = function (props) {
3240
3303
  var _d = useState([]), filteredValues = _d[0], setFilteredValues = _d[1];
3241
3304
  var optionsInitialising = useRef(false);
3242
3305
  var _e = useState(), options = _e[0], setOptions = _e[1];
3306
+ var invalid = useCallback(function () {
3307
+ var validations = pick(subComponentIsValid.current, Object.keys(selectedValues));
3308
+ return Object.values(validations).some(function (v) { return !v; });
3309
+ }, [selectedValues]);
3243
3310
  var save = useCallback(function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
3244
3311
  var validations, notValid, menuOptionSubValueResult;
3245
3312
  return __generator(this, function (_a) {
@@ -3333,8 +3400,9 @@ var GridFormMultiSelect = function (props) {
3333
3400
  }, [selectedValues]);
3334
3401
  var _f = useGridPopoverHook({
3335
3402
  className: props.className,
3403
+ invalid: invalid,
3336
3404
  save: save
3337
- }), popoverWrapper = _f.popoverWrapper, lastInputKeyboardEventHandlers = _f.lastInputKeyboardEventHandlers, triggerSave = _f.triggerSave;
3405
+ }), popoverWrapper = _f.popoverWrapper, triggerSave = _f.triggerSave;
3338
3406
  return popoverWrapper(jsx(ComponentLoadingWrapper, __assign({ loading: !options, className: "GridFormMultiSelect-container" }, { children: jsxs(Fragment$1, { children: [options && props.filtered && (jsxs(Fragment$1, { children: [jsx(FocusableItem, __assign({ className: "filter-item" }, { children: function (_a) {
3339
3407
  var _b;
3340
3408
  var ref = _a.ref;
@@ -3342,9 +3410,12 @@ var GridFormMultiSelect = function (props) {
3342
3410
  } }), "filter"), jsx(MenuDivider, {}, "$$divider_filter")] })), jsx("div", __assign({ className: "GridFormMultiSelect-options" }, { children: options === null || options === void 0 ? void 0 : options.map(function (item, index) {
3343
3411
  var _a;
3344
3412
  return item.value === MenuSeparatorString ? (jsx(MenuDivider, {}, "$$divider_".concat(index))) : filteredValues.includes(item.value) ? null : (jsxs("div", { children: [jsx(MenuItem, __assign({ onClick: function (e) {
3345
- e.keepOpen = true;
3346
- toggleValue(item);
3347
- } }, lastInputKeyboardEventHandlers, { children: jsx(LuiCheckboxInput, { isChecked: "".concat(item.value) in selectedValues, value: "".concat(item.value), label: (_a = item.label) !== null && _a !== void 0 ? _a : (item.value == null ? "<".concat(item.value, ">") : "".concat(item.value)), inputProps: {
3413
+ // Global react-menu MenuItem handler handles tabs
3414
+ if (e.key !== "Tab") {
3415
+ e.keepOpen = true;
3416
+ toggleValue(item);
3417
+ }
3418
+ } }, { children: jsx(LuiCheckboxInput, { isChecked: "".concat(item.value) in selectedValues, value: "".concat(item.value), label: (_a = item.label) !== null && _a !== void 0 ? _a : (item.value == null ? "<".concat(item.value, ">") : "".concat(item.value)), inputProps: {
3348
3419
  onClick: function (e) {
3349
3420
  e.preventDefault();
3350
3421
  e.stopPropagation();
@@ -3444,7 +3515,7 @@ var GridFormPopoverMenu = function (props) {
3444
3515
  });
3445
3516
  }); })();
3446
3517
  }, [options, props.defaultAction, props.options, selectedRows]);
3447
- var actionClick = useCallback(function (menuOption) { return __awaiter(void 0, void 0, void 0, function () {
3518
+ var actionClick = useCallback(function (menuOption, reason) { return __awaiter(void 0, void 0, void 0, function () {
3448
3519
  return __generator(this, function (_a) {
3449
3520
  actionProcessing.current = true;
3450
3521
  return [2 /*return*/, updateValue(function () { return __awaiter(void 0, void 0, void 0, function () {
@@ -3461,25 +3532,27 @@ var GridFormPopoverMenu = function (props) {
3461
3532
  return [2 /*return*/, true];
3462
3533
  }
3463
3534
  });
3464
- }); })];
3535
+ }); }, reason === CloseReason.TAB_FORWARD ? 1 : reason === CloseReason.TAB_BACKWARD ? -1 : 0)];
3465
3536
  });
3466
3537
  }); }, [defaultAction, selectedRows, subSelectedValue, updateValue]);
3467
- var onMenuItemClick = useCallback(function (e, item) {
3468
- if (item.subComponent) {
3469
- subComponentIsValid.current = false;
3470
- setSubSelectedValue(null);
3471
- setSubComponentSelected(subComponentSelected === item ? null : item);
3472
- e.keepOpen = true;
3473
- }
3474
- else {
3475
- actionClick(item).then();
3476
- e.keepOpen = true;
3477
- }
3478
- }, [actionClick, subComponentSelected]);
3479
- var selectedRowCount = selectedRows.length;
3480
- var filteredOptions = options === null || options === void 0 ? void 0 : options.filter(function (menuOption) {
3481
- return menuOption.label === PopoutMenuSeparator || selectedRowCount === 1 || menuOption.supportsMultiEdit;
3482
- });
3538
+ var onMenuItemClick = useCallback(function (e, item) { return __awaiter(void 0, void 0, void 0, function () {
3539
+ return __generator(this, function (_a) {
3540
+ switch (_a.label) {
3541
+ case 0:
3542
+ if (!item.subComponent) return [3 /*break*/, 1];
3543
+ subComponentIsValid.current = false;
3544
+ setSubSelectedValue(null);
3545
+ setSubComponentSelected(subComponentSelected === item ? null : item);
3546
+ e.keepOpen = true;
3547
+ return [3 /*break*/, 3];
3548
+ case 1: return [4 /*yield*/, actionClick(item, e.key === "Tab" ? (e.shiftKey ? CloseReason.TAB_BACKWARD : CloseReason.TAB_FORWARD) : CloseReason.CLICK).then()];
3549
+ case 2:
3550
+ _a.sent();
3551
+ _a.label = 3;
3552
+ case 3: return [2 /*return*/];
3553
+ }
3554
+ });
3555
+ }); }, [actionClick, subComponentSelected]);
3483
3556
  var save = useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
3484
3557
  return __generator(this, function (_a) {
3485
3558
  switch (_a.label) {
@@ -3487,19 +3560,23 @@ var GridFormPopoverMenu = function (props) {
3487
3560
  if (!(!actionProcessing.current && subComponentSelected)) return [3 /*break*/, 2];
3488
3561
  if (!subComponentIsValid.current)
3489
3562
  return [2 /*return*/, false];
3490
- return [4 /*yield*/, actionClick(subComponentSelected)];
3563
+ return [4 /*yield*/, actionClick(subComponentSelected, "click")];
3491
3564
  case 1:
3492
3565
  _a.sent();
3493
- return [2 /*return*/, false];
3566
+ return [2 /*return*/, true];
3494
3567
  case 2:
3495
3568
  // Otherwise assume it's a cancel, either way we close the menu
3496
3569
  return [2 /*return*/, true];
3497
3570
  }
3498
3571
  });
3499
3572
  }); }, [actionClick, subComponentSelected]);
3500
- var _e = useGridPopoverHook({ className: props.className, save: save }), popoverWrapper = _e.popoverWrapper, triggerSave = _e.triggerSave;
3501
- return popoverWrapper(jsx(ComponentLoadingWrapper, __assign({ loading: !filteredOptions, className: "GridFormPopupMenu" }, { children: jsx(Fragment$1, { children: options === null || options === void 0 ? void 0 : options.map(function (item, index) {
3502
- return item.label === PopoutMenuSeparator ? (jsx(MenuDivider, {}, "$$divider_".concat(index))) : (!item.hidden && (jsxs(Fragment, { children: [jsx(MenuItem, __assign({ onClick: function (e) { return onMenuItemClick(e, 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)), item.subComponent && subComponentSelected === item && (jsx(FocusableItem, __assign({ className: "LuiDeprecatedForms" }, { children: function (_) {
3573
+ var _e = useGridPopoverHook({
3574
+ className: props.className,
3575
+ invalid: function () { return subComponentSelected && !subComponentIsValid.current; },
3576
+ save: save
3577
+ }), popoverWrapper = _e.popoverWrapper, triggerSave = _e.triggerSave;
3578
+ return popoverWrapper(jsx(ComponentLoadingWrapper, __assign({ loading: !options, className: "GridFormPopupMenu" }, { children: jsx(Fragment$1, { children: options === null || options === void 0 ? void 0 : options.map(function (item, index) {
3579
+ return item.label === PopoutMenuSeparator ? (jsx(MenuDivider, {}, "$$divider_".concat(index))) : (!item.hidden && (jsxs(Fragment, { children: [jsx(MenuItem, __assign({ onClick: function (e) { return onMenuItemClick(e, item); }, disabled: !!item.disabled, title: item.disabled && typeof item.disabled !== "boolean" ? item.disabled : "" }, { children: item.label }), "".concat(item.label)), item.subComponent && subComponentSelected === item && (jsx(FocusableItem, __assign({ className: "LuiDeprecatedForms" }, { children: function (_) {
3503
3580
  return item.subComponent && (jsx(GridSubComponentContext.Provider, __assign({ value: {
3504
3581
  data: data,
3505
3582
  value: subSelectedValue,
@@ -3526,7 +3603,7 @@ var GridPopoverMenu = function (colDef, custom) {
3526
3603
  };
3527
3604
 
3528
3605
  var bearingValueFormatter = function (params) {
3529
- var value = params.value;
3606
+ var value = typeof params.value == "string" ? parseFloat(params.value) : params.value;
3530
3607
  if (value == null) {
3531
3608
  return "-";
3532
3609
  }
@@ -3609,28 +3686,33 @@ styleInject(css_248z$2);
3609
3686
  var css_248z$1 = ".LuiTextInput{margin-bottom:0}.LuiTextInput-formatted{color:#beb9b4;line-height:48px;position:absolute;right:14px;top:0}";
3610
3687
  styleInject(css_248z$1);
3611
3688
 
3689
+ var FormError = function (props) {
3690
+ return (jsxs(Fragment$1, { children: [props.error && (jsxs("span", __assign({ className: "LuiTextInput-error" }, { children: [jsx(LuiIcon, { alt: "error", name: "ic_error", className: "LuiTextInput-error-icon", size: "sm", status: "error" }), props.error] }))), props.helpText && !props.error && (jsx("span", __assign({ style: {
3691
+ fontSize: "0.7rem"
3692
+ } }, { children: props.helpText })))] }));
3693
+ };
3694
+
3612
3695
  var TextInputFormatted = function (props) {
3613
3696
  return (jsxs("div", __assign({ className: clsx("LuiTextInput Grid-popoverContainer", props.error && "hasError", props.className) }, { children: [jsxs("span", __assign({ className: "LuiTextInput-inputWrapper" }, { children: [jsx("input", __assign({ type: "text", spellCheck: true, defaultValue: props.value }, omit(props, ["error", "value", "helpText", "formatted", "className"]), { className: "LuiTextInput-input", onMouseEnter: function (e) {
3614
3697
  e.currentTarget.focus();
3615
3698
  props.onMouseEnter && props.onMouseEnter(e);
3616
- } })), jsx("span", __assign({ className: "LuiTextInput-formatted" }, { children: props.formatted }))] })), props.error && (jsxs("span", __assign({ className: "LuiTextInput-error" }, { children: [jsx(LuiIcon, { alt: "error", name: "ic_error", className: "LuiTextInput-error-icon", size: "sm", status: "error" }), props.error] }))), props.helpText && !props.error && (jsx("span", __assign({ style: {
3617
- fontSize: "0.7rem"
3618
- } }, { children: props.helpText })))] })));
3699
+ } })), jsx("span", __assign({ className: "LuiTextInput-formatted" }, { children: props.formatted }))] })), jsx(FormError, { error: props.error, helpText: props.helpText })] })));
3619
3700
  };
3620
3701
 
3621
3702
  var GridFormEditBearing = function (props) {
3622
3703
  var _a = useGridPopoverContext(), field = _a.field, initialValue = _a.value;
3623
- var _b = useState("".concat(initialValue !== null && initialValue !== void 0 ? initialValue : "")), value = _b[0], setValue = _b[1];
3704
+ // This clears out any scientific precision
3705
+ var defaultValue = useMemo(function () { return (initialValue == null ? "" : parseFloat(parseFloat(initialValue).toFixed(10)).toString()); }, [initialValue]);
3706
+ var _b = useState(defaultValue), value = _b[0], setValue = _b[1];
3707
+ var invalid = useCallback(function () { return bearingStringValidator(value, props.range); }, [props.range, value]);
3624
3708
  var save = useCallback(function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
3625
3709
  var parsedValue;
3626
3710
  return __generator(this, function (_a) {
3627
3711
  switch (_a.label) {
3628
3712
  case 0:
3629
- if (bearingStringValidator(value))
3630
- return [2 /*return*/, false];
3631
3713
  parsedValue = bearingNumberParser(value);
3632
3714
  // Value didn't change so don't save just cancel
3633
- if (parsedValue === initialValue) {
3715
+ if (parsedValue === bearingNumberParser(defaultValue)) {
3634
3716
  return [2 /*return*/, true];
3635
3717
  }
3636
3718
  if (!props.onSave) return [3 /*break*/, 2];
@@ -3649,14 +3731,15 @@ var GridFormEditBearing = function (props) {
3649
3731
  case 3: return [2 /*return*/, true];
3650
3732
  }
3651
3733
  });
3652
- }); }, [field, initialValue, props, value]);
3653
- var _c = useGridPopoverHook({
3734
+ }); }, [defaultValue, field, props, value]);
3735
+ var popoverWrapper = useGridPopoverHook({
3654
3736
  className: props.className,
3737
+ invalid: invalid,
3655
3738
  save: save
3656
- }), popoverWrapper = _c.popoverWrapper, onlyInputKeyboardEventHandlers = _c.onlyInputKeyboardEventHandlers;
3657
- return popoverWrapper(jsx("div", __assign({ className: "GridFormEditBearing-input Grid-popoverContainer" }, { children: jsx(TextInputFormatted, __assign({ value: value !== null && value !== void 0 ? value : "", onChange: function (e) {
3739
+ }).popoverWrapper;
3740
+ return popoverWrapper(jsx("div", __assign({ className: "GridFormEditBearing-input Grid-popoverContainer" }, { children: jsx(TextInputFormatted, { value: defaultValue, onChange: function (e) {
3658
3741
  setValue(e.target.value.trim());
3659
- }, autoFocus: true, placeholder: props.placeHolder }, onlyInputKeyboardEventHandlers, { formatted: bearingStringValidator(value, props.range) ? "?" : convertDDToDMS(bearingNumberParser(value)), error: bearingStringValidator(value, props.range) })) })));
3742
+ }, autoFocus: true, placeholder: props.placeHolder, formatted: bearingStringValidator(value, props.range) ? "?" : convertDDToDMS(bearingNumberParser(value)), error: bearingStringValidator(value, props.range), helpText: "Press enter or tab to save" }) })));
3660
3743
  };
3661
3744
 
3662
3745
  var GridPopoverEditBearingLike = function (colDef, props) {
@@ -3801,9 +3884,7 @@ var TextAreaInput = function (props) {
3801
3884
  e.currentTarget.selectionStart = e.currentTarget.value.length;
3802
3885
  }
3803
3886
  props.onMouseEnter && props.onMouseEnter(e);
3804
- } }, { children: props.value })) }))] })), props.error && (jsxs("span", __assign({ className: "LuiTextAreaInput-error" }, { children: [jsx(LuiIcon, { alt: "error", name: "ic_error", className: "LuiTextAreaInput-error-icon", size: "sm", status: "error" }), props.error] }))), props.helpText && !props.error && (jsx("span", __assign({ style: {
3805
- fontSize: "0.7rem"
3806
- } }, { children: props.helpText })))] })));
3887
+ } }, { children: props.value })) }))] })), jsx(FormError, { error: props.error, helpText: props.helpText })] })));
3807
3888
  };
3808
3889
 
3809
3890
  var TextInputValidator = function (props, value, data) {
@@ -3835,8 +3916,6 @@ var GridFormTextArea = function (props) {
3835
3916
  return __generator(this, function (_a) {
3836
3917
  switch (_a.label) {
3837
3918
  case 0:
3838
- if (invalid())
3839
- return [2 /*return*/, false];
3840
3919
  if (initialVale === (value !== null && value !== void 0 ? value : ""))
3841
3920
  return [2 /*return*/, true];
3842
3921
  if (!props.onSave) return [3 /*break*/, 2];
@@ -3853,9 +3932,13 @@ var GridFormTextArea = function (props) {
3853
3932
  return [2 /*return*/, true];
3854
3933
  }
3855
3934
  });
3856
- }); }, [invalid, initialVale, value, props, field]);
3857
- var _e = useGridPopoverHook({ className: props.className, save: save }), popoverWrapper = _e.popoverWrapper, onlyInputKeyboardEventHandlers = _e.onlyInputKeyboardEventHandlers;
3858
- return popoverWrapper(jsx("div", __assign({ style: { display: "flex", flexDirection: "row", width: (_b = props.width) !== null && _b !== void 0 ? _b : 240 } }, { children: jsx(TextAreaInput, __assign({ value: value, onChange: function (e) { return setValue(e.target.value); }, error: invalid(), placeholder: props.placeholder, helpText: helpText }, onlyInputKeyboardEventHandlers)) })));
3935
+ }); }, [initialVale, value, props, field]);
3936
+ var popoverWrapper = useGridPopoverHook({
3937
+ className: props.className,
3938
+ invalid: invalid,
3939
+ save: save
3940
+ }).popoverWrapper;
3941
+ return popoverWrapper(jsx("div", __assign({ style: { display: "flex", flexDirection: "row", width: (_b = props.width) !== null && _b !== void 0 ? _b : 240 } }, { children: jsx(TextAreaInput, { value: value, onChange: function (e) { return setValue(e.target.value); }, error: invalid(), placeholder: props.placeholder, helpText: helpText }) })));
3859
3942
  };
3860
3943
 
3861
3944
  var GridPopoverTextArea = function (colDef, params) { return GridCell(colDef, __assign({ editor: GridFormTextArea }, params)); };
@@ -3864,7 +3947,7 @@ var GridFormTextInput = function (props) {
3864
3947
  var _a, _b;
3865
3948
  var _c = useGridPopoverContext(), field = _c.field, initialVale = _c.value, data = _c.data;
3866
3949
  var helpText = (_a = props.helpText) !== null && _a !== void 0 ? _a : "Press enter or tab to save";
3867
- var initValue = initialVale == null ? "" : "".concat(initialVale);
3950
+ var initValue = useMemo(function () { return (initialVale == null ? "" : "".concat(initialVale)); }, [initialVale]);
3868
3951
  var _d = useState(initValue), value = _d[0], setValue = _d[1];
3869
3952
  var invalid = useCallback(function () { return TextInputValidator(props, value, data); }, [data, props, value]);
3870
3953
  var save = useCallback(function (selectedRows) { return __awaiter(void 0, void 0, void 0, function () {
@@ -3892,8 +3975,12 @@ var GridFormTextInput = function (props) {
3892
3975
  }
3893
3976
  });
3894
3977
  }); }, [invalid, value, initValue, props, field]);
3895
- var _e = useGridPopoverHook({ className: props.className, save: save }), popoverWrapper = _e.popoverWrapper, onlyInputKeyboardEventHandlers = _e.onlyInputKeyboardEventHandlers;
3896
- return popoverWrapper(jsx("div", __assign({ style: { display: "flex", flexDirection: "row", width: (_b = props.width) !== null && _b !== void 0 ? _b : 240 }, className: "FormTest" }, { children: jsx(TextInputFormatted, __assign({ value: value, onChange: function (e) { return setValue(e.target.value); }, error: invalid(), formatted: props.units, style: { width: "100%" }, placeholder: props.placeholder }, onlyInputKeyboardEventHandlers, { helpText: helpText })) })));
3978
+ var popoverWrapper = useGridPopoverHook({
3979
+ className: props.className,
3980
+ invalid: invalid,
3981
+ save: save
3982
+ }).popoverWrapper;
3983
+ return popoverWrapper(jsx("div", __assign({ style: { display: "flex", flexDirection: "row", width: (_b = props.width) !== null && _b !== void 0 ? _b : 240 }, className: "FormTest" }, { children: jsx(TextInputFormatted, { value: value, onChange: function (e) { return setValue(e.target.value); }, error: invalid(), formatted: props.units, style: { width: "100%" }, placeholder: props.placeholder, helpText: helpText }) })));
3897
3984
  };
3898
3985
 
3899
3986
  var GridPopoverTextInput = function (colDef, params) {
@@ -3902,7 +3989,7 @@ var GridPopoverTextInput = function (colDef, params) {
3902
3989
 
3903
3990
  var GridFormSubComponentTextInput = function (props) {
3904
3991
  var _a;
3905
- var _b = useContext(GridSubComponentContext), value = _b.value, setValue = _b.setValue, setValid = _b.setValid, triggerSave = _b.triggerSave, data = _b.data;
3992
+ var _b = useContext(GridSubComponentContext), value = _b.value, setValue = _b.setValue, setValid = _b.setValid, data = _b.data;
3906
3993
  var helpText = (_a = props.helpText) !== null && _a !== void 0 ? _a : "Press enter or tab to save";
3907
3994
  // If is not initialised yet as it's just been created then set the default value
3908
3995
  useEffect(function () {
@@ -3913,30 +4000,14 @@ var GridFormSubComponentTextInput = function (props) {
3913
4000
  useEffect(function () {
3914
4001
  setValid(value != null && invalid() == null);
3915
4002
  }, [setValid, invalid, value]);
3916
- return (jsx(TextInputFormatted, { value: value, error: invalid(), onChange: function (e) { return setValue(e.target.value); }, helpText: helpText, autoFocus: true, onKeyDown: function (e) {
3917
- if (e.key === "Tab" || e.key === "Enter") {
3918
- e.preventDefault();
3919
- e.stopPropagation();
3920
- }
3921
- }, onKeyUp: function (e) {
3922
- if (e.key === "Tab") {
3923
- e.preventDefault();
3924
- e.stopPropagation();
3925
- !e.shiftKey && triggerSave().then();
3926
- }
3927
- else if (e.key === "Enter") {
3928
- triggerSave().then();
3929
- e.preventDefault();
3930
- e.stopPropagation();
3931
- }
3932
- }, placeholder: props.placeholder, style: {
4003
+ return (jsx(TextInputFormatted, { value: value, error: invalid(), onChange: function (e) { return setValue(e.target.value); }, helpText: helpText, autoFocus: true, placeholder: props.placeholder, style: {
3933
4004
  width: "100%"
3934
4005
  } }));
3935
4006
  };
3936
4007
 
3937
4008
  var GridFormSubComponentTextArea = function (props) {
3938
4009
  var _a;
3939
- var _b = useContext(GridSubComponentContext), value = _b.value, data = _b.data, setValue = _b.setValue, setValid = _b.setValid, triggerSave = _b.triggerSave;
4010
+ var _b = useContext(GridSubComponentContext), value = _b.value, data = _b.data, setValue = _b.setValue, setValid = _b.setValid;
3940
4011
  var helpText = (_a = props.helpText) !== null && _a !== void 0 ? _a : "Press tab to save";
3941
4012
  // If is not initialised yet as it's just been created then set the default value
3942
4013
  useEffect(function () {
@@ -3947,18 +4018,7 @@ var GridFormSubComponentTextArea = function (props) {
3947
4018
  useEffect(function () {
3948
4019
  setValid(value != null && invalid() == null);
3949
4020
  }, [setValid, invalid, value]);
3950
- return (jsx("div", __assign({ className: clsx("FreeTextInput LuiDeprecatedForms", props.className) }, { children: jsx(TextAreaInput, { className: "free-text-input", value: value, onChange: function (e) { return setValue(e.target.value); }, error: invalid(), helpText: helpText, autoFocus: true, placeholder: props.placeholder, onKeyDown: function (e) {
3951
- if (e.key === "Tab") {
3952
- e.preventDefault();
3953
- e.stopPropagation();
3954
- }
3955
- }, onKeyUp: function (e) {
3956
- if (e.key === "Tab") {
3957
- e.preventDefault();
3958
- e.stopPropagation();
3959
- !e.shiftKey && triggerSave().then();
3960
- }
3961
- } }) })));
4021
+ return (jsx("div", __assign({ className: clsx("FreeTextInput LuiDeprecatedForms", props.className) }, { children: jsx(TextAreaInput, { className: "free-text-input", value: value, onChange: function (e) { return setValue(e.target.value); }, error: invalid(), helpText: helpText, autoFocus: true, placeholder: props.placeholder }) })));
3962
4022
  };
3963
4023
 
3964
4024
  var css_248z = ".ActionButton{align-items:center;display:flex}.ActionButton .LuiIcon{margin:0 4px!important}.ActionButton-minimalArea{position:relative}.ActionButton-minimalAreaDisplay{position:absolute}.ActionButton-minimalAreaExpand{visibility:hidden}.ActionButton-inProgress{background-color:#e2f3f7!important;color:#007198!important;cursor:progress}.ActionButton-inProgress svg *{fill:#0000!important}";