@linzjs/step-ag-grid 2.1.2 → 2.2.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 (72) hide show
  1. package/README.md +2 -2
  2. package/dist/index.js +122 -25
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/components/Grid.d.ts +1 -0
  5. package/dist/src/components/GridCell.d.ts +1 -1
  6. package/dist/src/components/gridForm/GridFormEditBearing.d.ts +1 -1
  7. package/dist/src/components/gridForm/GridFormMessage.d.ts +1 -1
  8. package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +1 -1
  9. package/dist/src/components/gridForm/GridFormPopoutMenu.d.ts +1 -1
  10. package/dist/src/components/gridForm/GridFormTextArea.d.ts +1 -1
  11. package/dist/src/components/gridForm/GridFormTextInput.d.ts +1 -1
  12. package/dist/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.d.ts +1 -1
  13. package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +1 -1
  14. package/dist/src/components/gridPopoverEdit/GridPopoverEditDropDown.d.ts +1 -1
  15. package/dist/src/components/gridPopoverEdit/GridPopoverMenu.d.ts +1 -1
  16. package/dist/src/components/gridPopoverEdit/GridPopoverMessage.d.ts +1 -1
  17. package/dist/src/components/gridPopoverEdit/GridPopoverTextArea.d.ts +1 -1
  18. package/dist/src/components/gridPopoverEdit/GridPopoverTextInput.d.ts +1 -1
  19. package/dist/src/components/gridRender/GridRenderGenericCell.d.ts +1 -1
  20. package/dist/src/contexts/GridContext.d.ts +1 -1
  21. package/dist/src/index.d.ts +29 -28
  22. package/dist/src/lui/ActionButton.d.ts +15 -0
  23. package/dist/src/lui/reactUtils.d.ts +6 -0
  24. package/dist/src/lui/reactUtils.test.d.ts +1 -0
  25. package/dist/src/lui/stateDeferredHook.d.ts +4 -0
  26. package/dist/src/lui/timeoutHook.d.ts +8 -0
  27. package/dist/src/lui/timeoutHook.test.d.ts +1 -0
  28. package/dist/step-ag-grid.esm.js +123 -27
  29. package/dist/step-ag-grid.esm.js.map +1 -1
  30. package/package.json +6 -4
  31. package/src/components/Grid.tsx +5 -4
  32. package/src/components/GridCell.tsx +7 -7
  33. package/src/components/GridPopoverHook.tsx +3 -3
  34. package/src/components/PostSortRowsHook.ts +8 -2
  35. package/src/components/gridForm/GridFormDropDown.tsx +2 -2
  36. package/src/components/gridForm/GridFormEditBearing.tsx +2 -2
  37. package/src/components/gridForm/GridFormMessage.tsx +1 -1
  38. package/src/components/gridForm/GridFormMultiSelect.tsx +3 -3
  39. package/src/components/gridForm/GridFormPopoutMenu.tsx +3 -3
  40. package/src/components/gridForm/GridFormTextArea.tsx +1 -1
  41. package/src/components/gridForm/GridFormTextInput.tsx +1 -1
  42. package/src/components/gridPopoverEdit/GridPopoutEditMultiSelect.ts +1 -3
  43. package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +2 -4
  44. package/src/components/gridPopoverEdit/GridPopoverEditDropDown.ts +1 -3
  45. package/src/components/gridPopoverEdit/GridPopoverMenu.tsx +1 -1
  46. package/src/components/gridPopoverEdit/GridPopoverMessage.ts +1 -1
  47. package/src/components/gridPopoverEdit/GridPopoverTextArea.ts +1 -1
  48. package/src/components/gridPopoverEdit/GridPopoverTextInput.ts +1 -1
  49. package/src/components/gridRender/GridRenderGenericCell.tsx +2 -2
  50. package/src/components/gridRender/GridRenderPopoutMenuCell.tsx +1 -1
  51. package/src/contexts/GridContext.tsx +1 -1
  52. package/src/contexts/GridContextProvider.tsx +2 -2
  53. package/src/contexts/GridPopoverContextProvider.tsx +2 -2
  54. package/src/index.ts +34 -32
  55. package/src/lui/ActionButton.scss +32 -0
  56. package/src/lui/ActionButton.tsx +76 -0
  57. package/src/lui/reactUtils.test.tsx +47 -0
  58. package/src/lui/reactUtils.tsx +14 -0
  59. package/src/lui/stateDeferredHook.tsx +29 -0
  60. package/src/lui/timeoutHook.test.tsx +38 -0
  61. package/src/lui/timeoutHook.tsx +40 -0
  62. package/src/react-menu3/components/ControlledMenu.tsx +1 -1
  63. package/src/stories/components/ActionButton.stories.tsx +33 -0
  64. package/src/stories/{components → grid}/FormTest.scss +0 -0
  65. package/src/stories/{components → grid}/FormTest.tsx +4 -4
  66. package/src/stories/{components → grid}/GridPopoutBearing.stories.tsx +13 -16
  67. package/src/stories/{components → grid}/GridPopoutEditDropDown.stories.tsx +27 -30
  68. package/src/stories/{components → grid}/GridPopoutEditGeneric.stories.tsx +10 -13
  69. package/src/stories/{components → grid}/GridPopoutEditGenericTextArea.stories.tsx +64 -25
  70. package/src/stories/{components → grid}/GridPopoutEditMultiSelect.stories.tsx +15 -18
  71. package/src/stories/{components → grid}/GridReadOnly.stories.tsx +13 -15
  72. package/src/stories/{components → react-menu}/ReactMenu.stories.tsx +2 -2
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@linzjs/step-ag-grid",
3
3
  "repository": "github:linz/step-ag-grid.git",
4
4
  "license": "MIT",
5
- "version": "2.1.2",
5
+ "version": "2.2.0",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -13,7 +13,7 @@
13
13
  "react-component"
14
14
  ],
15
15
  "main": "dist/index.js",
16
- "typings": "dist/index.d.ts",
16
+ "typings": "dist/src/index.d.ts",
17
17
  "module": "dist/step-ag-grid.esm.js",
18
18
  "files": [
19
19
  "dist",
@@ -91,9 +91,10 @@
91
91
  "@storybook/react": "6.5.13",
92
92
  "@storybook/test-runner": "^0.9.0",
93
93
  "@storybook/testing-library": "^0.0.13",
94
+ "@testing-library/dom": "^8.19.0",
94
95
  "@testing-library/jest-dom": "^5.16.5",
95
- "@testing-library/react": "^13.4.0",
96
- "@testing-library/user-event": "^14.4.3",
96
+ "@testing-library/react": "^12.1.5",
97
+ "@testing-library/user-event": "^13.5.0",
97
98
  "@types/debounce-promise": "^3.1.5",
98
99
  "@types/jest": "^29.2.2",
99
100
  "@types/lodash-es": "^4.17.6",
@@ -105,6 +106,7 @@
105
106
  "babel-jest": "^29.2.2",
106
107
  "babel-preset-react-app": "^10.0.1",
107
108
  "chromatic": "^6.11.4",
109
+ "conventional-changelog-conventionalcommits": "^5.0.0",
108
110
  "eslint": "^8.26.0",
109
111
  "eslint-config-prettier": "^8.5.0",
110
112
  "eslint-config-react-app": "^7.0.1",
@@ -5,11 +5,11 @@ import { CellClickedEvent, ColDef } from "ag-grid-community";
5
5
  import { CellEvent, GridReadyEvent, SelectionChangedEvent } from "ag-grid-community/dist/lib/events";
6
6
  import { GridOptions } from "ag-grid-community/dist/lib/entities/gridOptions";
7
7
  import { difference, last, xorBy } from "lodash-es";
8
- import { GridContext } from "@contexts/GridContext";
8
+ import { GridContext } from "../contexts/GridContext";
9
9
  import { usePostSortRowsHook } from "./PostSortRowsHook";
10
- import { isNotEmpty } from "@utils/util";
10
+ import { isNotEmpty } from "../utils/util";
11
11
  import { GridHeaderSelect } from "./gridHeader/GridHeaderSelect";
12
- import { GridUpdatingContext } from "@contexts/GridUpdatingContext";
12
+ import { GridUpdatingContext } from "../contexts/GridUpdatingContext";
13
13
 
14
14
  export interface GridBaseRow {
15
15
  id: string | number;
@@ -28,6 +28,7 @@ export interface GridProps {
28
28
  columnDefs: GridOptions["columnDefs"];
29
29
  rowData: GridOptions["rowData"];
30
30
  noRowsOverlayText?: string;
31
+ postSortRows?: GridOptions["postSortRows"];
31
32
  }
32
33
 
33
34
  /**
@@ -264,7 +265,7 @@ export const Grid = (params: GridProps): JSX.Element => {
264
265
  noRowsOverlayComponent={noRowsOverlayComponent}
265
266
  onGridReady={onGridReady}
266
267
  onSortChanged={ensureSelectedRowIsVisible}
267
- postSortRows={postSortRows}
268
+ postSortRows={params.postSortRows ?? postSortRows}
268
269
  onSelectionChanged={synchroniseExternalStateToGridSelection}
269
270
  />
270
271
  </div>
@@ -1,6 +1,6 @@
1
1
  import { forwardRef, useContext } from "react";
2
2
  import { GridBaseRow } from "./Grid";
3
- import { GridUpdatingContext } from "@contexts/GridUpdatingContext";
3
+ import { GridUpdatingContext } from "../contexts/GridUpdatingContext";
4
4
  import { GenericMultiEditCellClass } from "./GenericCellClass";
5
5
  import {
6
6
  GenericCellColDef,
@@ -9,10 +9,10 @@ import {
9
9
  } from "./gridRender/GridRenderGenericCell";
10
10
  import { ColDef, ICellEditorParams, ICellRendererParams } from "ag-grid-community";
11
11
  import { GridLoadableCell } from "./GridLoadableCell";
12
- import { GridIcon } from "@components/GridIcon";
12
+ import { GridIcon } from "../components/GridIcon";
13
13
  import { ValueFormatterParams } from "ag-grid-community/dist/lib/entities/colDef";
14
- import { GridPopoverContext } from "@contexts/GridPopoverContext";
15
- import { GridPopoverContextProvider } from "@contexts/GridPopoverContextProvider";
14
+ import { GridPopoverContext } from "../contexts/GridPopoverContext";
15
+ import { GridPopoverContextProvider } from "../contexts/GridPopoverContextProvider";
16
16
 
17
17
  export interface GenericCellEditorProps<E> {
18
18
  multiEdit?: boolean;
@@ -49,9 +49,9 @@ export interface ColDefT<RowType extends GridBaseRow> extends ColDef {
49
49
  }
50
50
 
51
51
  /*
52
- * For editing a text area.
52
+ * All cells should use this
53
53
  */
54
- export const GridCell = <RowType extends GridBaseRow, Props>(
54
+ export const GridCell = <RowType extends GridBaseRow, Props extends CellEditorCommon>(
55
55
  props: GenericCellColDef<RowType>,
56
56
  custom?: {
57
57
  multiEdit?: boolean;
@@ -120,7 +120,7 @@ const GenericCellEditorComponent3 = (props: ICellEditorParams & { editor: (props
120
120
 
121
121
  return (
122
122
  <>
123
- <div>{colDef.cellRenderer ? <colDef.cellRenderer {...props} /> : props.value}</div>
123
+ {<colDef.cellRenderer {...props} />}
124
124
  {props?.editor && <props.editor {...cellEditorParams} {...propsRef.current} />}
125
125
  </>
126
126
  );
@@ -1,8 +1,8 @@
1
1
  import { useCallback, useContext, useEffect, useRef, useState } from "react";
2
- import { GridContext } from "@contexts/GridContext";
2
+ import { GridContext } from "../contexts/GridContext";
3
3
  import { GridBaseRow } from "./Grid";
4
- import { ControlledMenu } from "@react-menu3";
5
- import { GridPopoverContext } from "@contexts/GridPopoverContext";
4
+ import { ControlledMenu } from "../react-menu3";
5
+ import { GridPopoverContext } from "../contexts/GridPopoverContext";
6
6
 
7
7
  export interface GridPopoverHookProps<RowType> {
8
8
  className: string | undefined;
@@ -53,8 +53,13 @@ export const usePostSortRowsHook = ({ setStaleGrid }: PostSortRowsHookProps) =>
53
53
 
54
54
  const hasNewRows = () => nodes.some((row) => previousRowSortIndex[row.data.id] == null);
55
55
 
56
- const sortIsStale = () =>
57
- !hasNewRows() && nodes.some((row, index) => ![null, index].includes(previousRowSortIndex[row.data.id] ?? null));
56
+ const sortIsStale = () => {
57
+ // If there are new rows we want to them to be at the bottom of the grid, so we treat it as sort not stale
58
+ if (hasNewRows()) return false;
59
+
60
+ // Otherwise check if the stored sort index matches the new sort index
61
+ return nodes.some((node, index) => previousRowSortIndex[node.data.id] != index);
62
+ };
58
63
 
59
64
  const sortNodesByPreviousSort = () =>
60
65
  nodes.sort(
@@ -115,6 +120,7 @@ export const usePostSortRowsHook = ({ setStaleGrid }: PostSortRowsHookProps) =>
115
120
  if (!sortWasStale.current) {
116
121
  // backup sort state, so we can restore it when sort is clicked on a stale column
117
122
  previousColSort.current = copyCurrentSortSettings();
123
+ backupSortOrder();
118
124
  sortWasStale.current = true;
119
125
  setStaleGrid(true);
120
126
  }
@@ -1,10 +1,10 @@
1
1
  import "../../styles/GridFormDropDown.scss";
2
2
 
3
- import { MenuItem, MenuDivider, FocusableItem, MenuHeader } from "@react-menu3";
3
+ import { MenuItem, MenuDivider, FocusableItem, MenuHeader } from "../../react-menu3";
4
4
  import { useCallback, useContext, useEffect, useRef, useState, KeyboardEvent } from "react";
5
5
  import { GridBaseRow } from "../Grid";
6
6
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
7
- import { GridContext } from "@contexts/GridContext";
7
+ import { GridContext } from "../../contexts/GridContext";
8
8
  import { delay } from "lodash-es";
9
9
  import debounce from "debounce-promise";
10
10
  import { CellEditorCommon, CellParams } from "../GridCell";
@@ -3,9 +3,9 @@ import "../../styles/GridFormEditBearing.scss";
3
3
  import { useCallback, useState } from "react";
4
4
  import { GridBaseRow } from "../Grid";
5
5
  import { TextInputFormatted } from "../../lui/TextInputFormatted";
6
- import { bearingNumberParser, bearingStringValidator, convertDDToDMS } from "@utils/bearing";
6
+ import { bearingNumberParser, bearingStringValidator, convertDDToDMS } from "../../utils/bearing";
7
7
  import { useGridPopoverHook } from "../GridPopoverHook";
8
- import { CellEditorCommon, CellParams } from "@components/GridCell";
8
+ import { CellEditorCommon, CellParams } from "../GridCell";
9
9
 
10
10
  export interface GridFormEditBearingProps<RowType extends GridBaseRow> extends CellEditorCommon {
11
11
  placeHolder?: string;
@@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
3
3
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
4
4
  import { GridBaseRow } from "../Grid";
5
5
  import { useGridPopoverHook } from "../GridPopoverHook";
6
- import { CellEditorCommon, CellParams } from "@components/GridCell";
6
+ import { CellEditorCommon, CellParams } from "../GridCell";
7
7
 
8
8
  export interface GridFormMessageProps<RowType extends GridBaseRow> extends CellEditorCommon {
9
9
  message: (cellParams: CellParams<RowType>) => Promise<string | JSX.Element> | string | JSX.Element;
@@ -1,14 +1,14 @@
1
1
  import "../../styles/GridFormMultiSelect.scss";
2
2
 
3
- import { MenuItem, MenuDivider, FocusableItem } from "@react-menu3";
3
+ import { MenuItem, MenuDivider, FocusableItem } from "../../react-menu3";
4
4
  import { useCallback, useEffect, useRef, useState, KeyboardEvent } from "react";
5
5
  import { GridBaseRow } from "../Grid";
6
6
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
7
7
  import { delay, fromPairs } from "lodash-es";
8
8
  import { LuiCheckboxInput } from "@linzjs/lui";
9
9
  import { useGridPopoverHook } from "../GridPopoverHook";
10
- import { MenuSeparatorString } from "@components/gridForm/GridFormDropDown";
11
- import { CellEditorCommon, CellParams } from "@components/GridCell";
10
+ import { MenuSeparatorString } from "./GridFormDropDown";
11
+ import { CellEditorCommon, CellParams } from "../GridCell";
12
12
  import { ClickEvent } from "../../react-menu3/types";
13
13
 
14
14
  interface MultiFinalSelectOption<ValueType> {
@@ -1,10 +1,10 @@
1
1
  import { GridBaseRow } from "../Grid";
2
2
  import { useCallback, useContext, useEffect, useRef, useState } from "react";
3
- import { GridContext } from "@contexts/GridContext";
3
+ import { GridContext } from "../../contexts/GridContext";
4
4
  import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
5
- import { MenuDivider, MenuItem } from "@react-menu3";
5
+ import { MenuDivider, MenuItem } from "../../react-menu3";
6
6
  import { useGridPopoverHook } from "../GridPopoverHook";
7
- import { CellEditorCommon, CellParams } from "@components/GridCell";
7
+ import { CellEditorCommon, CellParams } from "../GridCell";
8
8
 
9
9
  export interface GridFormPopoutMenuProps<RowType extends GridBaseRow> extends CellEditorCommon {
10
10
  options: (selectedRows: RowType[]) => Promise<MenuOption<RowType>[]>;
@@ -2,7 +2,7 @@ import { useCallback, useState } from "react";
2
2
  import { TextAreaInput } from "../../lui/TextAreaInput";
3
3
  import { useGridPopoverHook } from "../GridPopoverHook";
4
4
  import { GridBaseRow } from "../Grid";
5
- import { CellEditorCommon, CellParams } from "@components/GridCell";
5
+ import { CellEditorCommon, CellParams } from "../GridCell";
6
6
 
7
7
  export interface GridFormTextAreaProps<RowType extends GridBaseRow> extends CellEditorCommon {
8
8
  placeholder?: string;
@@ -2,7 +2,7 @@ import { useCallback, useState } from "react";
2
2
  import { TextInputFormatted } from "../../lui/TextInputFormatted";
3
3
  import { useGridPopoverHook } from "../GridPopoverHook";
4
4
  import { GridBaseRow } from "../Grid";
5
- import { CellEditorCommon, CellParams } from "@components/GridCell";
5
+ import { CellEditorCommon, CellParams } from "../GridCell";
6
6
 
7
7
  export interface GridFormTextInputProps<RowType extends GridBaseRow> extends CellEditorCommon {
8
8
  placeholder?: string;
@@ -1,8 +1,7 @@
1
- import { GenericMultiEditCellClass } from "../GenericCellClass";
2
1
  import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
3
2
  import { GridBaseRow } from "../Grid";
4
3
  import { GridFormMultiSelect, GridFormMultiSelectProps } from "../gridForm/GridFormMultiSelect";
5
- import { GenericCellColDef } from "@components/gridRender/GridRenderGenericCell";
4
+ import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
6
5
 
7
6
  export const GridPopoutEditMultiSelect = <RowType extends GridBaseRow, ValueType>(
8
7
  colDef: GenericCellColDef<RowType>,
@@ -12,7 +11,6 @@ export const GridPopoutEditMultiSelect = <RowType extends GridBaseRow, ValueType
12
11
  {
13
12
  initialWidth: 65,
14
13
  maxWidth: 150,
15
- cellClass: props.multiEdit ? GenericMultiEditCellClass : undefined,
16
14
  ...colDef,
17
15
  },
18
16
  {
@@ -1,9 +1,8 @@
1
- import { GenericMultiEditCellClass } from "../GenericCellClass";
2
- import { bearingCorrectionValueFormatter, bearingValueFormatter } from "@utils/bearing";
1
+ import { bearingCorrectionValueFormatter, bearingValueFormatter } from "../../utils/bearing";
3
2
  import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
4
3
  import { GridFormEditBearing, GridFormEditBearingProps } from "../gridForm/GridFormEditBearing";
5
4
  import { GridBaseRow } from "../Grid";
6
- import { GenericCellColDef } from "@components/gridRender/GridRenderGenericCell";
5
+ import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
7
6
 
8
7
  export const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
9
8
  colDef: GenericCellColDef<RowType>,
@@ -14,7 +13,6 @@ export const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
14
13
  initialWidth: 65,
15
14
  maxWidth: 150,
16
15
  valueFormatter: bearingValueFormatter,
17
- cellClass: props.multiEdit ? GenericMultiEditCellClass : undefined,
18
16
  ...colDef,
19
17
  },
20
18
  {
@@ -1,8 +1,7 @@
1
- import { GenericMultiEditCellClass } from "../GenericCellClass";
2
1
  import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
3
2
  import { GridBaseRow } from "../Grid";
4
3
  import { GridFormDropDown, GridFormPopoutDropDownProps } from "../gridForm/GridFormDropDown";
5
- import { GenericCellColDef } from "@components/gridRender/GridRenderGenericCell";
4
+ import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
6
5
 
7
6
  export const GridPopoverEditDropDown = <RowType extends GridBaseRow, ValueType>(
8
7
  colDef: GenericCellColDef<RowType>,
@@ -12,7 +11,6 @@ export const GridPopoverEditDropDown = <RowType extends GridBaseRow, ValueType>(
12
11
  {
13
12
  initialWidth: 65,
14
13
  maxWidth: 150,
15
- cellClass: props.multiEdit ? GenericMultiEditCellClass : undefined,
16
14
  ...colDef,
17
15
  },
18
16
  {
@@ -5,7 +5,7 @@ import { GridBaseRow } from "../Grid";
5
5
  import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
6
6
  import { GridFormPopoutMenu, GridFormPopoutMenuProps } from "../gridForm/GridFormPopoutMenu";
7
7
  import { GridRenderPopoutMenuCell } from "../gridRender/GridRenderPopoutMenuCell";
8
- import { GenericCellColDef } from "@components/gridRender/GridRenderGenericCell";
8
+ import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
9
9
 
10
10
  /**
11
11
  * Popout burger menu
@@ -1,7 +1,7 @@
1
1
  import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
2
2
  import { GridFormMessage, GridFormMessageProps } from "../gridForm/GridFormMessage";
3
3
  import { GridBaseRow } from "../Grid";
4
- import { GenericCellColDef } from "@components/gridRender/GridRenderGenericCell";
4
+ import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
5
5
 
6
6
  export const GridPopoverMessage = <RowType extends GridBaseRow>(
7
7
  colDef: GenericCellColDef<RowType>,
@@ -1,7 +1,7 @@
1
1
  import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
2
2
  import { GridBaseRow } from "../Grid";
3
3
  import { GridFormTextArea, GridFormTextAreaProps } from "../gridForm/GridFormTextArea";
4
- import { GenericCellColDef } from "@components/gridRender/GridRenderGenericCell";
4
+ import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
5
5
 
6
6
  export const GridPopoverTextArea = <RowType extends GridBaseRow>(
7
7
  colDef: GenericCellColDef<RowType>,
@@ -1,7 +1,7 @@
1
1
  import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
2
2
  import { GridBaseRow } from "../Grid";
3
3
  import { GridFormTextInput, GridFormTextInputProps } from "../gridForm/GridFormTextInput";
4
- import { GenericCellColDef } from "@components/gridRender/GridRenderGenericCell";
4
+ import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
5
5
 
6
6
  export const GridPopoverTextInput = <RowType extends GridBaseRow>(
7
7
  colDef: GenericCellColDef<RowType>,
@@ -1,13 +1,13 @@
1
1
  import "../../styles/GridRenderGenericCell.scss";
2
2
 
3
3
  import { useContext } from "react";
4
- import { GridUpdatingContext } from "@contexts/GridUpdatingContext";
4
+ import { GridUpdatingContext } from "../../contexts/GridUpdatingContext";
5
5
  import { GridLoadableCell } from "../GridLoadableCell";
6
6
  import { GridIcon } from "../GridIcon";
7
7
  import { ColDef, ICellRendererParams } from "ag-grid-community";
8
8
  import { ValueFormatterParams } from "ag-grid-community/dist/lib/entities/colDef";
9
9
  import { GridBaseRow } from "../Grid";
10
- import { ColDefT } from "@components/GridCell";
10
+ import { ColDefT } from "../GridCell";
11
11
 
12
12
  export interface RowICellRendererParams<RowType extends GridBaseRow> extends ICellRendererParams {
13
13
  data: RowType;
@@ -1,6 +1,6 @@
1
1
  import { useContext } from "react";
2
2
  import { ColDef, ICellRendererParams } from "ag-grid-community";
3
- import { GridUpdatingContext } from "@contexts/GridUpdatingContext";
3
+ import { GridUpdatingContext } from "../../contexts/GridUpdatingContext";
4
4
  import { GridLoadableCell } from "../GridLoadableCell";
5
5
  import { LuiIcon } from "@linzjs/lui";
6
6
  import { Column } from "ag-grid-community/dist/lib/entities/column";
@@ -1,6 +1,6 @@
1
1
  import { createContext } from "react";
2
2
  import { GridApi } from "ag-grid-community";
3
- import { GridBaseRow } from "@components/Grid";
3
+ import { GridBaseRow } from "../components/Grid";
4
4
 
5
5
  export interface GridContextType {
6
6
  gridReady: () => boolean;
@@ -2,9 +2,9 @@ import { ReactElement, ReactNode, useContext, useRef } from "react";
2
2
  import { GridApi, RowNode } from "ag-grid-community";
3
3
  import { GridContext } from "./GridContext";
4
4
  import { delay, difference, isEmpty, last, sortBy } from "lodash-es";
5
- import { isNotEmpty } from "@utils/util";
5
+ import { isNotEmpty } from "../utils/util";
6
6
  import { GridUpdatingContext } from "./GridUpdatingContext";
7
- import { GridBaseRow } from "@components/Grid";
7
+ import { GridBaseRow } from "../components/Grid";
8
8
 
9
9
  interface GridContextProps {
10
10
  children: ReactNode;
@@ -1,9 +1,9 @@
1
1
  import { ReactNode, RefObject, useCallback, useContext, useRef, useState } from "react";
2
2
  import { GridPopoverContext, PropsType } from "./GridPopoverContext";
3
3
  import { ICellEditorParams } from "ag-grid-community";
4
- import { GridContext } from "@contexts/GridContext";
4
+ import { GridContext } from "./GridContext";
5
5
  import { sortBy } from "lodash-es";
6
- import { GridBaseRow } from "@components/Grid";
6
+ import { GridBaseRow } from "../components/Grid";
7
7
 
8
8
  interface GridPopoverContextProps {
9
9
  children: ReactNode;
package/src/index.ts CHANGED
@@ -1,38 +1,40 @@
1
- export * from "@react-menu3";
1
+ export * from "./react-menu3/index";
2
2
  export * from "./react-menu3/types";
3
3
 
4
- export * from "@contexts/GridUpdatingContext";
5
- export * from "@contexts/GridUpdatingContextProvider";
6
- export * from "@contexts/GridContext";
7
- export * from "@contexts/GridContextProvider";
8
-
9
- export type { GridBaseRow } from "@components/Grid";
10
- export { Grid } from "@components/Grid";
11
- export * from "@components/GridCell";
12
- export { GridIcon } from "@components/GridIcon";
13
- export { ComponentLoadingWrapper } from "@components/ComponentLoadingWrapper";
14
- export { GenericMultiEditCellClass } from "@components/GenericCellClass";
15
- export { GridLoadableCell } from "@components/GridLoadableCell";
16
- export { useGridPopoverHook } from "@components/GridPopoverHook";
17
- export { usePostSortRowsHook } from "@components/PostSortRowsHook";
18
-
19
- export { GridRendererGenericCell } from "@components/gridRender/GridRenderGenericCell";
20
- export { GridRenderPopoutMenuCell } from "@components/gridRender/GridRenderPopoutMenuCell";
21
-
22
- export { GridPopoutEditMultiSelect } from "@components/gridPopoverEdit/GridPopoutEditMultiSelect";
23
- export { GridPopoverMenu } from "@components/gridPopoverEdit/GridPopoverMenu";
24
- export { GridPopoverEditBearing } from "@components/gridPopoverEdit/GridPopoverEditBearing";
25
- export { GridPopoverEditBearingCorrection } from "@components/gridPopoverEdit/GridPopoverEditBearing";
26
- export { GridPopoverEditDropDown } from "@components/gridPopoverEdit/GridPopoverEditDropDown";
27
- export { GridPopoverMessage } from "@components/gridPopoverEdit/GridPopoverMessage";
28
- export { GridPopoverTextArea } from "@components/gridPopoverEdit/GridPopoverTextArea";
29
- export { GridPopoverTextInput } from "@components/gridPopoverEdit/GridPopoverTextInput";
30
-
31
- export { GridHeaderSelect } from "@components/gridHeader/GridHeaderSelect";
4
+ export * from "./contexts/GridUpdatingContext";
5
+ export * from "./contexts/GridUpdatingContextProvider";
6
+ export * from "./contexts/GridContext";
7
+ export * from "./contexts/GridContextProvider";
8
+
9
+ export type { GridBaseRow } from "./components/Grid";
10
+ export { Grid } from "./components/Grid";
11
+ export * from "./components/GridCell";
12
+ export { GridIcon } from "./components/GridIcon";
13
+ export { ComponentLoadingWrapper } from "./components/ComponentLoadingWrapper";
14
+ export { GenericMultiEditCellClass } from "./components/GenericCellClass";
15
+ export { GridLoadableCell } from "./components/GridLoadableCell";
16
+ export { useGridPopoverHook } from "./components/GridPopoverHook";
17
+ export { usePostSortRowsHook } from "./components/PostSortRowsHook";
18
+
19
+ export * from "./components/gridRender/GridRenderGenericCell";
20
+ export { GridRenderPopoutMenuCell } from "./components/gridRender/GridRenderPopoutMenuCell";
21
+
22
+ export { GridPopoutEditMultiSelect } from "./components/gridPopoverEdit/GridPopoutEditMultiSelect";
23
+ export { GridPopoverMenu } from "./components/gridPopoverEdit/GridPopoverMenu";
24
+ export { GridPopoverEditBearing } from "./components/gridPopoverEdit/GridPopoverEditBearing";
25
+ export { GridPopoverEditBearingCorrection } from "./components/gridPopoverEdit/GridPopoverEditBearing";
26
+ export { GridPopoverEditDropDown } from "./components/gridPopoverEdit/GridPopoverEditDropDown";
27
+ export { GridPopoverMessage } from "./components/gridPopoverEdit/GridPopoverMessage";
28
+ export { GridPopoverTextArea } from "./components/gridPopoverEdit/GridPopoverTextArea";
29
+ export { GridPopoverTextInput } from "./components/gridPopoverEdit/GridPopoverTextInput";
30
+
31
+ export { GridHeaderSelect } from "./components/gridHeader/GridHeaderSelect";
32
32
 
33
33
  export { TextAreaInput } from "./lui/TextAreaInput";
34
34
  export { TextInputFormatted } from "./lui/TextInputFormatted";
35
- export { GridSubComponentTextArea } from "@components/GridSubComponentTextArea";
35
+ export { GridSubComponentTextArea } from "./components/GridSubComponentTextArea";
36
+
37
+ export * from "./lui/ActionButton";
36
38
 
37
- export * from "@utils/bearing";
38
- export * from "@utils/util";
39
+ export * from "./utils/bearing";
40
+ export * from "./utils/util";
@@ -0,0 +1,32 @@
1
+ @use "../../node_modules/@linzjs/lui/dist/scss/Foundation/Variables/ColorVars" as colors;
2
+
3
+ .ActionButton {
4
+ display: flex;
5
+ align-items: center;
6
+ }
7
+
8
+ .ActionButton .LuiIcon {
9
+ margin: 0 4px !important;
10
+ }
11
+
12
+ .ActionButton-minimalArea {
13
+ position: relative;
14
+ }
15
+
16
+ .ActionButton-minimalAreaDisplay {
17
+ position: absolute;
18
+ }
19
+
20
+ .ActionButton-minimalAreaExpand {
21
+ visibility: hidden;
22
+ }
23
+
24
+ .ActionButton-inProgress {
25
+ cursor: progress;
26
+ color: #007198 !important;
27
+ background-color: colors.$polar !important;
28
+
29
+ svg * {
30
+ fill: transparent !important;
31
+ }
32
+ }
@@ -0,0 +1,76 @@
1
+ import "./ActionButton.scss";
2
+
3
+ import clsx from "clsx";
4
+ import { useEffect } from "react";
5
+ import { LuiButton, LuiIcon, LuiMiniSpinner } from "@linzjs/lui";
6
+ import { IconName } from "@linzjs/lui/dist/components/LuiIcon/LuiIcon";
7
+ import { usePrevious } from "./reactUtils";
8
+ import { useStateDeferred } from "./stateDeferredHook";
9
+
10
+ export interface ActionButtonProps {
11
+ icon: IconName;
12
+ name: string;
13
+ inProgressName?: string;
14
+ title?: string;
15
+ dataTestId?: string;
16
+ size?: "xs" | "sm" | "md" | "lg" | "xl" | "ns";
17
+ className?: string;
18
+ onClick?: () => void;
19
+ inProgress?: boolean;
20
+ }
21
+
22
+ // Kept this less than one second, so I don't have issues with waitFor as it defaults to 1s
23
+ const minimumInProgressTimeMs = 950;
24
+
25
+ export const ActionButton = ({
26
+ icon,
27
+ name,
28
+ inProgressName,
29
+ dataTestId,
30
+ inProgress,
31
+ className,
32
+ title,
33
+ onClick,
34
+ size = "sm",
35
+ }: ActionButtonProps): JSX.Element => {
36
+ const lastInProgress = usePrevious(inProgress ?? false);
37
+ const [localInProgress, setLocalInProgress, setLocalInProgressDeferred] = useStateDeferred<boolean>(!!inProgress);
38
+
39
+ useEffect(() => {
40
+ if (inProgress == lastInProgress) return;
41
+ inProgress ? setLocalInProgress(true) : setLocalInProgressDeferred(false, minimumInProgressTimeMs);
42
+ }, [inProgress, lastInProgress, setLocalInProgress, setLocalInProgressDeferred]);
43
+
44
+ return (
45
+ <LuiButton
46
+ data-testid={dataTestId}
47
+ type={"button"}
48
+ level={"tertiary"}
49
+ title={title ?? name}
50
+ aria-label={name}
51
+ className={clsx("lui-button-icon", "ActionButton", className, localInProgress && "ActionButton-inProgress")}
52
+ size={"lg"}
53
+ onClick={onClick}
54
+ disabled={localInProgress}
55
+ >
56
+ {localInProgress ? (
57
+ <LuiMiniSpinner
58
+ size={16}
59
+ divProps={{
60
+ "data-testid": "loading-spinner",
61
+ style: { padding: 0, margin: 0, paddingRight: 8 },
62
+ role: "status",
63
+ ["aria-label"]: "Loading",
64
+ }}
65
+ />
66
+ ) : (
67
+ <LuiIcon name={icon} alt={name} size={size} />
68
+ )}
69
+ <span className={"ActionButton-minimalArea"}>
70
+ <span className={"ActionButton-minimalAreaDisplay"}>{(localInProgress ? inProgressName : name) ?? name}</span>
71
+ {/* This makes sure the button expands to fill maximum length text at all times */}
72
+ <span className={"ActionButton-minimalAreaExpand"}>{name}</span>
73
+ </span>
74
+ </LuiButton>
75
+ );
76
+ };
@@ -0,0 +1,47 @@
1
+ import { usePrevious } from "./reactUtils";
2
+ import { useEffect, useState } from "react";
3
+ import { act, render } from "@testing-library/react";
4
+ import { screen } from "@testing-library/dom";
5
+
6
+ interface WrapperProps {
7
+ value: boolean;
8
+ }
9
+
10
+ let extPrevious: boolean | undefined = undefined;
11
+
12
+ const UsePreviousWrapper = ({ value }: WrapperProps): JSX.Element => {
13
+ const previous = usePrevious<boolean>(value);
14
+ useEffect(() => {
15
+ extPrevious = previous;
16
+ }, [previous]);
17
+
18
+ return <div />;
19
+ };
20
+
21
+ const TestComponent = (): JSX.Element => {
22
+ const [value, setValue] = useState(false);
23
+
24
+ const toggleValue = () => setValue((value) => !value);
25
+
26
+ return (
27
+ <>
28
+ <button onClick={toggleValue}>Change value</button>
29
+ <UsePreviousWrapper value={value} />
30
+ </>
31
+ );
32
+ };
33
+
34
+ describe("usePrevious", () => {
35
+ test("usePrevious", async () => {
36
+ render(<TestComponent />);
37
+ const button = await screen.findByText("Change value");
38
+
39
+ expect(extPrevious).toBeUndefined();
40
+
41
+ act(() => button.click());
42
+ expect(extPrevious).toBe(false);
43
+
44
+ act(() => button.click());
45
+ expect(extPrevious).toBe(true);
46
+ });
47
+ });