@linzjs/step-ag-grid 7.19.5 → 8.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 (29) hide show
  1. package/dist/src/components/Grid.d.ts +2 -1
  2. package/dist/src/components/gridForm/GridFormEditBearing.d.ts +5 -1
  3. package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +8 -2
  4. package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +8 -2
  5. package/dist/src/components/gridForm/GridFormTextArea.d.ts +4 -1
  6. package/dist/src/components/gridForm/GridFormTextInput.d.ts +4 -1
  7. package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +10 -1
  8. package/dist/src/utils/bearing.d.ts +2 -3
  9. package/dist/step-ag-grid.esm.js +67 -47
  10. package/dist/step-ag-grid.esm.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/components/Grid.tsx +3 -3
  13. package/src/components/gridForm/GridFormEditBearing.tsx +9 -4
  14. package/src/components/gridForm/GridFormMultiSelect.tsx +7 -7
  15. package/src/components/gridForm/GridFormPopoverMenu.tsx +9 -7
  16. package/src/components/gridForm/GridFormTextArea.tsx +2 -2
  17. package/src/components/gridForm/GridFormTextInput.tsx +4 -7
  18. package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +40 -32
  19. package/src/react-menu3/components/ControlledMenu.tsx +5 -1
  20. package/src/stories/grid/GridNonEditableRow.stories.tsx +6 -6
  21. package/src/stories/grid/GridPopoutBearing.stories.tsx +1 -1
  22. package/src/stories/grid/GridPopoutEditGenericTextArea.stories.tsx +5 -5
  23. package/src/stories/grid/GridPopoutEditMultiSelect.stories.tsx +3 -3
  24. package/src/stories/grid/GridReadOnly.stories.tsx +6 -6
  25. package/src/stories/grid/gridForm/GridFormDropDown.stories.tsx +60 -0
  26. package/src/stories/grid/gridForm/GridFormEditBearing.stories.tsx +56 -0
  27. package/src/stories/grid/gridForm/GridFormEditBearingCorrection.stories.tsx +56 -0
  28. package/src/stories/grid/gridForm/reactMenuTest.scss +3 -0
  29. package/src/utils/bearing.ts +10 -12
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": "7.19.5",
5
+ "version": "8.0.0",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -27,7 +27,7 @@ export interface GridProps {
27
27
  externalSelectedItems?: any[];
28
28
  setExternalSelectedItems?: (items: any[]) => void;
29
29
  defaultColDef?: GridOptions["defaultColDef"];
30
- columnDefs: GridOptions["columnDefs"];
30
+ columnDefs: ColDef[];
31
31
  rowData: GridOptions["rowData"];
32
32
  noRowsOverlayText?: string;
33
33
  postSortRows?: GridOptions["postSortRows"];
@@ -168,8 +168,8 @@ export const Grid = (params: GridProps): JSX.Element => {
168
168
  synchroniseExternallySelectedItemsToGrid();
169
169
  }, [synchroniseExternallySelectedItemsToGrid]);
170
170
 
171
- const columnDefs = useMemo((): GridOptions["columnDefs"] => {
172
- const adjustColDefs = (params.columnDefs as ColDef[]).map((colDef) => {
171
+ const columnDefs = useMemo((): ColDef[] => {
172
+ const adjustColDefs = params.columnDefs.map((colDef) => {
173
173
  return {
174
174
  ...colDef,
175
175
  editable: params.readOnly ? false : params.defaultColDef?.editable ?? colDef.editable,
@@ -7,13 +7,14 @@ import { CellEditorCommon } from "../GridCell";
7
7
  import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
8
8
 
9
9
  export interface GridFormEditBearingProps<RowType extends GridBaseRow> extends CellEditorCommon {
10
+ formatValue?: (value: any) => string;
10
11
  placeHolder?: string;
11
12
  range?: (value: number | null) => string | null;
12
- onSave?: (selectedRows: RowType[], value: number | null) => Promise<boolean>;
13
+ onSave?: (props: { selectedRows: RowType[]; value: number | null }) => Promise<boolean>;
13
14
  }
14
15
 
15
16
  export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridFormEditBearingProps<RowType>) => {
16
- const { field, value: initialValue, formatValue } = useGridPopoverContext<RowType>();
17
+ const { field, value: initialValue } = useGridPopoverContext<RowType>();
17
18
 
18
19
  // This clears out any scientific precision
19
20
  const defaultValue = useMemo(
@@ -34,7 +35,7 @@ export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridForm
34
35
  }
35
36
 
36
37
  if (props.onSave) {
37
- return await props.onSave(selectedRows, parsedValue);
38
+ return await props.onSave({ selectedRows, value: parsedValue });
38
39
  } else {
39
40
  if (field == null) {
40
41
  console.error("field is not defined in ColDef");
@@ -63,7 +64,11 @@ export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridForm
63
64
  }}
64
65
  autoFocus={true}
65
66
  placeholder={props.placeHolder}
66
- formatted={bearingStringValidator(value, props.range) ? "?" : formatValue(bearingNumberParser(value))}
67
+ formatted={
68
+ bearingStringValidator(value, props.range) || !props.formatValue
69
+ ? "?"
70
+ : props.formatValue(bearingNumberParser(value))
71
+ }
67
72
  error={bearingStringValidator(value, props.range)}
68
73
  helpText={"Press enter or tab to save"}
69
74
  />
@@ -52,8 +52,8 @@ export interface GridFormMultiSelectProps<RowType extends GridBaseRow> extends C
52
52
  filtered?: boolean;
53
53
  filterPlaceholder?: string;
54
54
  filterHelpText?: string | ((filter: string, options: MultiSelectOption[]) => string | undefined);
55
- onSelectFilter?: (filter: string, options: MultiSelectOption[]) => void;
56
- onSave?: (selectedRows: RowType[], selectedOptions: MultiSelectOption[]) => Promise<boolean>;
55
+ onSelectFilter?: (props: { filter: string; options: MultiSelectOption[] }) => void;
56
+ onSave?: (props: { selectedRows: RowType[]; selectedOptions: MultiSelectOption[] }) => Promise<boolean>;
57
57
  headers?: GridFormMultiSelectGroup[];
58
58
  options: MultiSelectOption[] | ((selectedRows: RowType[]) => Promise<MultiSelectOption[]> | MultiSelectOption[]);
59
59
  invalid?: (selectedRows: RowType[], selectedOptions: MultiSelectOption[]) => boolean;
@@ -90,10 +90,10 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
90
90
  // Any changes to save?
91
91
  if (initialValues === JSON.stringify(options)) return true;
92
92
 
93
- return props.onSave(
93
+ return props.onSave({
94
94
  selectedRows,
95
- options.filter((o) => o.checked),
96
- );
95
+ selectedOptions: options.filter((o) => o.checked),
96
+ });
97
97
  },
98
98
  [initialValues, options, props],
99
99
  );
@@ -203,7 +203,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
203
203
  const FilterInput = (props: {
204
204
  options: MultiSelectOption[];
205
205
  setOptions: (options: MultiSelectOption[]) => void;
206
- onSelectFilter?: (filter: string, options: MultiSelectOption[]) => void;
206
+ onSelectFilter?: (props: { filter: string; options: MultiSelectOption[] }) => void;
207
207
  filter: string;
208
208
  setFilter: Dispatch<SetStateAction<string>>;
209
209
  headerGroups: HeaderGroupType;
@@ -259,7 +259,7 @@ const FilterInput = (props: {
259
259
  }
260
260
 
261
261
  const preFilterOptions = JSON.stringify(options);
262
- onSelectFilter(filterTrimmed, options);
262
+ onSelectFilter({ filter: filterTrimmed, options });
263
263
  // Detect if options list changed and update
264
264
  if (preFilterOptions === JSON.stringify(options)) return;
265
265
 
@@ -10,7 +10,7 @@ import { useGridPopoverContext } from "../../contexts/GridPopoverContext";
10
10
 
11
11
  export interface GridFormPopoutMenuProps<RowType extends GridBaseRow> extends CellEditorCommon {
12
12
  options: (selectedRows: RowType[]) => Promise<MenuOption<RowType>[]>;
13
- defaultAction?: (selectedRows: RowType[], menuOption: SelectedMenuOptionResult<RowType>) => Promise<void>;
13
+ defaultAction?: (props: { selectedRows: RowType[]; menuOption: SelectedMenuOptionResult<RowType> }) => Promise<void>;
14
14
  }
15
15
 
16
16
  /** Menu configuration types **/
@@ -26,7 +26,7 @@ export interface SelectedMenuOptionResult<RowType extends GridBaseRow> extends M
26
26
 
27
27
  export interface MenuOption<RowType extends GridBaseRow> {
28
28
  label: JSX.Element | string | MenuSeparatorType;
29
- action?: (selectedRows: RowType[], menuOption: SelectedMenuOptionResult<RowType>) => Promise<void>;
29
+ action?: (props: { selectedRows: RowType[]; menuOption: SelectedMenuOptionResult<RowType> }) => Promise<void>;
30
30
  disabled?: string | boolean;
31
31
  hidden?: boolean;
32
32
  subComponent?: (props: any) => JSX.Element;
@@ -47,9 +47,9 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
47
47
  const [subSelectedValue, setSubSelectedValue] = useState<any>();
48
48
 
49
49
  const defaultAction = useCallback(
50
- async (selectedRows: RowType[], menuOption: SelectedMenuOptionResult<RowType>) => {
51
- if (props.defaultAction) await props.defaultAction(selectedRows, menuOption);
52
- else console.error(`No action specified for ${menuOption.label} menu options`);
50
+ async (params: { selectedRows: RowType[]; menuOption: SelectedMenuOptionResult<RowType> }) => {
51
+ if (props.defaultAction) await props.defaultAction(params);
52
+ else console.error(`No action specified for ${params.menuOption.label} menu options`);
53
53
  },
54
54
  [props],
55
55
  );
@@ -77,8 +77,10 @@ export const GridFormPopoverMenu = <RowType extends GridBaseRow>(props: GridForm
77
77
 
78
78
  const actionClick = useCallback(
79
79
  async (menuOption: MenuOption<RowType>) => {
80
- const result = { ...menuOption, subValue: subSelectedValue };
81
- await (menuOption.action ?? defaultAction)(selectedRows, result);
80
+ await (menuOption.action ?? defaultAction)({
81
+ selectedRows,
82
+ menuOption: { ...menuOption, subValue: subSelectedValue },
83
+ });
82
84
  return true;
83
85
  },
84
86
  [defaultAction, selectedRows, subSelectedValue],
@@ -11,7 +11,7 @@ export interface GridFormTextAreaProps<RowType extends GridBaseRow>
11
11
  CellEditorCommon {
12
12
  placeholder?: string;
13
13
  width?: string | number;
14
- onSave?: (selectedRows: RowType[], value: string) => Promise<boolean>;
14
+ onSave?: (props: { selectedRows: RowType[]; value: string }) => Promise<boolean>;
15
15
  helpText?: string;
16
16
  }
17
17
 
@@ -34,7 +34,7 @@ export const GridFormTextArea = <RowType extends GridBaseRow>(props: GridFormTex
34
34
  if (initValue === trimmedValue) return true;
35
35
 
36
36
  if (props.onSave) {
37
- return await props.onSave(selectedRows, trimmedValue);
37
+ return await props.onSave({ selectedRows, value: trimmedValue });
38
38
  }
39
39
 
40
40
  selectedRows.forEach((row) => (row[field] = trimmedValue as any));
@@ -12,7 +12,7 @@ export interface GridFormTextInputProps<RowType extends GridBaseRow>
12
12
  placeholder?: string;
13
13
  units?: string;
14
14
  width?: string | number;
15
- onSave?: (selectedRows: RowType[], value: string) => Promise<boolean>;
15
+ onSave?: (props: { selectedRows: RowType[]; value: string }) => Promise<boolean>;
16
16
  helpText?: string;
17
17
  }
18
18
 
@@ -35,7 +35,7 @@ export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormTe
35
35
  if (initValue === trimmedValue) return true;
36
36
 
37
37
  if (props.onSave) {
38
- return await props.onSave(selectedRows, trimmedValue);
38
+ return await props.onSave({ selectedRows, value: trimmedValue });
39
39
  }
40
40
 
41
41
  selectedRows.forEach((row) => (row[field] = trimmedValue as any));
@@ -50,16 +50,13 @@ export const GridFormTextInput = <RowType extends GridBaseRow>(props: GridFormTe
50
50
  });
51
51
 
52
52
  return popoverWrapper(
53
- <div
54
- style={{ display: "flex", flexDirection: "row", width: props.width ?? 240 }}
55
- className={"FormTest subComponent"}
56
- >
53
+ <div style={{ display: "flex", flexDirection: "row" }} className={"FormTest subComponent"}>
57
54
  <TextInputFormatted
58
55
  value={value}
59
56
  onChange={(e) => setValue(e.target.value)}
60
57
  error={invalid()}
61
58
  formatted={props.units}
62
- style={{ width: "100%" }}
59
+ style={{ width: props.width ?? 240 }}
63
60
  placeholder={props.placeholder}
64
61
  helpText={helpText}
65
62
  />
@@ -3,15 +3,19 @@ import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
3
3
  import { GridFormEditBearing, GridFormEditBearingProps } from "../gridForm/GridFormEditBearing";
4
4
  import { GridBaseRow } from "../Grid";
5
5
  import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
6
+ import { ValueFormatterParams } from "ag-grid-community/dist/lib/entities/colDef";
6
7
 
7
- export const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
8
+ const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
8
9
  colDef: GenericCellColDef<RowType>,
9
- props: GenericCellEditorProps<GridFormEditBearingProps<RowType>>,
10
+ props: GenericCellEditorProps<GridFormEditBearingProps<RowType>> & {
11
+ editorParams: { formatValue: (value: any) => any };
12
+ },
10
13
  ): ColDefT<RowType> =>
11
14
  GridCell(
12
15
  {
13
16
  initialWidth: 65,
14
17
  maxWidth: 150,
18
+ valueFormatter: (params: ValueFormatterParams) => props.editorParams?.formatValue(params.value) ?? "",
15
19
  ...colDef,
16
20
  },
17
21
  {
@@ -20,44 +24,48 @@ export const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
20
24
  },
21
25
  );
22
26
 
27
+ export const GridPopoverEditBearingEditorParams = {
28
+ placeHolder: "Enter bearing",
29
+ formatValue: bearingValueFormatter,
30
+ range: (value: number | null) => {
31
+ if (value === null) return "Bearing is required";
32
+ if (value >= 360) return "Bearing must be less than 360 degrees";
33
+ if (value < 0) return "Bearing must not be negative";
34
+ return null;
35
+ },
36
+ };
37
+
23
38
  export const GridPopoverEditBearing = <RowType extends GridBaseRow>(
24
39
  colDef: GenericCellColDef<RowType>,
25
40
  props: GenericCellEditorProps<GridFormEditBearingProps<RowType>>,
26
41
  ): ColDefT<RowType> =>
27
- GridPopoverEditBearingLike(
28
- { valueFormatter: bearingValueFormatter, ...colDef },
29
- {
30
- multiEdit: !!props.multiEdit,
31
- editorParams: {
32
- placeHolder: "Enter bearing correction",
33
- range: (value: number | null) => {
34
- if (value === null) return "Bearing correction is required";
35
- if (value >= 360) return "Bearing correction must be less than 360 degrees";
36
- if (value < 0) return "Bearing correction must not be negative";
37
- return null;
38
- },
39
- ...props.editorParams,
40
- },
42
+ GridPopoverEditBearingLike(colDef, {
43
+ multiEdit: !!props.multiEdit,
44
+ editorParams: {
45
+ ...GridPopoverEditBearingEditorParams,
46
+ ...props.editorParams,
41
47
  },
42
- );
48
+ });
49
+
50
+ export const GridPopoverEditBearingCorrectionEditorParams = {
51
+ placeHolder: "Enter bearing correction",
52
+ formatValue: bearingCorrectionValueFormatter,
53
+ range: (value: number | null) => {
54
+ if (value === null) return "Bearing correction is required";
55
+ if (value >= 360) return "Bearing correction must be less than 360 degrees";
56
+ if (value <= -180) return "Bearing correction must be greater then -180 degrees";
57
+ return null;
58
+ },
59
+ };
43
60
 
44
61
  export const GridPopoverEditBearingCorrection = <RowType extends GridBaseRow>(
45
62
  colDef: GenericCellColDef<RowType>,
46
63
  props: GenericCellEditorProps<GridFormEditBearingProps<RowType>>,
47
64
  ): ColDefT<RowType> =>
48
- GridPopoverEditBearingLike(
49
- { valueFormatter: bearingCorrectionValueFormatter, ...colDef },
50
- {
51
- multiEdit: !!props.multiEdit,
52
- editorParams: {
53
- placeHolder: "Enter bearing correction",
54
- range: (value: number | null) => {
55
- if (value === null) return "Bearing is required";
56
- if (value >= 360) return "Bearing must be less than 360 degrees";
57
- if (value <= -180) return "Bearing must be greater then -180 degrees";
58
- return null;
59
- },
60
- ...props.editorParams,
61
- },
65
+ GridPopoverEditBearingLike(colDef, {
66
+ multiEdit: !!props.multiEdit,
67
+ editorParams: {
68
+ ...GridPopoverEditBearingCorrectionEditorParams,
69
+ ...props.editorParams,
62
70
  },
63
- );
71
+ });
@@ -346,7 +346,11 @@ export const ControlledMenuFr = (
346
346
  );
347
347
 
348
348
  if (portal === true && anchorRef?.current != null) {
349
- portal = { target: anchorRef.current.ownerDocument.body } as PortalFieldType;
349
+ if (hasParentClass("react-menu-inline-test", anchorRef.current)) {
350
+ portal = false;
351
+ } else {
352
+ portal = { target: anchorRef.current.ownerDocument.body } as PortalFieldType;
353
+ }
350
354
  }
351
355
 
352
356
  if (portal) {
@@ -100,7 +100,7 @@ const GridNonEditableRowTemplate: ComponentStory<typeof Grid> = (props: GridProp
100
100
  return [
101
101
  {
102
102
  label: "Single edit only",
103
- action: async (selectedRows) => {
103
+ action: async ({ selectedRows }) => {
104
104
  alert(`Single-edit: ${selectedRows.map((r) => r.id)} rowId(s) selected`);
105
105
  await wait(1500);
106
106
  },
@@ -108,7 +108,7 @@ const GridNonEditableRowTemplate: ComponentStory<typeof Grid> = (props: GridProp
108
108
  },
109
109
  {
110
110
  label: "Multi-edit",
111
- action: async (selectedRows) => {
111
+ action: async ({ selectedRows }) => {
112
112
  alert(`Multi-edit: ${selectedRows.map((r) => r.id)} rowId(s) selected`);
113
113
  await wait(1500);
114
114
  },
@@ -123,9 +123,9 @@ const GridNonEditableRowTemplate: ComponentStory<typeof Grid> = (props: GridProp
123
123
  },
124
124
  {
125
125
  label: "Other (TextInput)",
126
- action: async (_, menuOptionResult) => {
126
+ action: async ({ menuOption }) => {
127
127
  // eslint-disable-next-line no-console
128
- console.log(`Sub selected value was ${JSON.stringify(menuOptionResult.subValue)}`);
128
+ console.log(`Sub selected value was ${JSON.stringify(menuOption.subValue)}`);
129
129
  await wait(500);
130
130
  },
131
131
  subComponent: () => (
@@ -134,9 +134,9 @@ const GridNonEditableRowTemplate: ComponentStory<typeof Grid> = (props: GridProp
134
134
  },
135
135
  {
136
136
  label: "Other (TextArea)",
137
- action: async (_, menuOptionResult) => {
137
+ action: async ({ menuOption }) => {
138
138
  // eslint-disable-next-line no-console
139
- console.log(`Sub selected value was ${JSON.stringify(menuOptionResult.subValue)}`);
139
+ console.log(`Sub selected value was ${JSON.stringify(menuOption.subValue)}`);
140
140
  await wait(500);
141
141
  },
142
142
  subComponent: () => (
@@ -72,7 +72,7 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
72
72
  },
73
73
  {
74
74
  editorParams: {
75
- onSave: async (selectedRows, value: ITestRow["bearing"]) => {
75
+ onSave: async ({ selectedRows, value }) => {
76
76
  await wait(1000);
77
77
  selectedRows.forEach((row) => (row["bearing"] = value));
78
78
  return true;
@@ -72,7 +72,7 @@ const GridPopoutEditGenericTemplate: ComponentStory<typeof Grid> = (props: GridP
72
72
  if (value === "never") return "The value 'never' is not allowed";
73
73
  return null;
74
74
  },
75
- onSave: async (selectedRows, value) => {
75
+ onSave: async ({ selectedRows, value }) => {
76
76
  await wait(1000);
77
77
  selectedRows.forEach((selectedRow) => (selectedRow["name"] = value));
78
78
  return true;
@@ -87,7 +87,7 @@ const GridPopoutEditGenericTemplate: ComponentStory<typeof Grid> = (props: GridP
87
87
  maxWidth: 140,
88
88
  valueFormatter: (params) => {
89
89
  const v = params.data.distance;
90
- return v != null ? `${v}${params.colDef.cellEditorParams.units}` : v;
90
+ return v != null ? `${v}${params.colDef.cellEditorParams.units}` : "–";
91
91
  },
92
92
  },
93
93
  {
@@ -100,7 +100,7 @@ const GridPopoutEditGenericTemplate: ComponentStory<typeof Grid> = (props: GridP
100
100
  if (value.length && !isFloat(value)) return "Value must be a number";
101
101
  return null;
102
102
  },
103
- onSave: async (selectedRows, value) => {
103
+ onSave: async ({ selectedRows, value }) => {
104
104
  await wait(1000);
105
105
  selectedRows.forEach(
106
106
  (selectedRow) => (selectedRow["distance"] = value.length ? parseFloat(value) : null),
@@ -126,7 +126,7 @@ const GridPopoutEditGenericTemplate: ComponentStory<typeof Grid> = (props: GridP
126
126
  if (value === "never") return "The value 'never' is not allowed";
127
127
  return null;
128
128
  },
129
- onSave: async (selectedRows, value) => {
129
+ onSave: async ({ selectedRows, value }) => {
130
130
  await wait(1000);
131
131
  selectedRows.forEach((selectedRow) => (selectedRow["plan"] = value));
132
132
  return true;
@@ -170,7 +170,7 @@ const GridPopoutEditGenericTemplate: ComponentStory<typeof Grid> = (props: GridP
170
170
  options: async (_) => [
171
171
  {
172
172
  label: "Delete",
173
- action: async (selectedRows) => {
173
+ action: async ({ selectedRows }) => {
174
174
  await wait(1500);
175
175
  setRowData(rowData.filter((data) => !selectedRows.some((row) => row.id == data.id)));
176
176
  },
@@ -96,7 +96,7 @@ const GridEditMultiSelectTemplate: ComponentStory<typeof Grid> = (props: GridPro
96
96
  subComponent: () => <GridFormSubComponentTextArea required={true} maxLength={5} defaultValue={""} />,
97
97
  },
98
98
  ],
99
- onSave: async (selectedRows, selectedOptions) => {
99
+ onSave: async ({ selectedRows, selectedOptions }) => {
100
100
  // eslint-disable-next-line no-console
101
101
  console.log("multiSelect result", { selectedRows, selectedOptions });
102
102
 
@@ -129,7 +129,7 @@ const GridEditMultiSelectTemplate: ComponentStory<typeof Grid> = (props: GridPro
129
129
  isEmpty(filter) || options.find((o) => o.label && o.label.toLowerCase() === filter.toLowerCase())
130
130
  ? undefined
131
131
  : "Press enter to add free text",
132
- onSelectFilter: async (filter, options) => {
132
+ onSelectFilter: async ({ filter, options }) => {
133
133
  if (isEmpty(filter) || options.find((o) => o.label && o.label.toLowerCase() === filter.toLowerCase()))
134
134
  return;
135
135
  options.push({ value: filter, label: filter, filter: "freeText", checked: true });
@@ -159,7 +159,7 @@ const GridEditMultiSelectTemplate: ComponentStory<typeof Grid> = (props: GridPro
159
159
  );
160
160
  return r;
161
161
  },
162
- onSave: async (selectedRows, selectedOptions) => {
162
+ onSave: async ({ selectedRows, selectedOptions }) => {
163
163
  // eslint-disable-next-line no-console
164
164
  console.log("multiSelect result", { selectedRows, selectedOptions });
165
165
 
@@ -126,7 +126,7 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
126
126
  return [
127
127
  {
128
128
  label: "Single edit only",
129
- action: async (selectedRows) => {
129
+ action: async ({ selectedRows }) => {
130
130
  alert(`Single-edit: ${selectedRows.map((r) => r.id)} rowId(s) selected`);
131
131
  await wait(1500);
132
132
  },
@@ -134,7 +134,7 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
134
134
  },
135
135
  {
136
136
  label: "Multi-edit",
137
- action: async (selectedRows) => {
137
+ action: async ({ selectedRows }) => {
138
138
  alert(`Multi-edit: ${selectedRows.map((r) => r.id)} rowId(s) selected`);
139
139
  await wait(1500);
140
140
  },
@@ -149,9 +149,9 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
149
149
  },
150
150
  {
151
151
  label: "Other (TextInput)",
152
- action: async (_, menuOptionResult) => {
152
+ action: async ({ menuOption }) => {
153
153
  // eslint-disable-next-line no-console
154
- console.log(`Sub selected value was ${JSON.stringify(menuOptionResult.subValue)}`);
154
+ console.log(`Sub selected value was ${JSON.stringify(menuOption.subValue)}`);
155
155
  await wait(500);
156
156
  },
157
157
  subComponent: () => (
@@ -160,9 +160,9 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
160
160
  },
161
161
  {
162
162
  label: "Other (TextArea)",
163
- action: async (_, menuOptionResult) => {
163
+ action: async ({ menuOption }) => {
164
164
  // eslint-disable-next-line no-console
165
- console.log(`Sub selected value was ${JSON.stringify(menuOptionResult.subValue)}`);
165
+ console.log(`Sub selected value was ${JSON.stringify(menuOption.subValue)}`);
166
166
  await wait(500);
167
167
  },
168
168
  subComponent: () => (
@@ -0,0 +1,60 @@
1
+ import "@linzjs/lui/dist/scss/base.scss";
2
+ import "@linzjs/lui/dist/fonts";
3
+ // Force react-menu not to render static inline not absolute
4
+ import "./reactMenuTest.scss";
5
+
6
+ import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
7
+ import { GridFormDropDown, MenuHeaderItem } from "../../../components/gridForm/GridFormDropDown";
8
+ import { GridContextProvider } from "../../../contexts/GridContextProvider";
9
+ import { GridPopoverContext, GridPopoverContextType } from "contexts/GridPopoverContext";
10
+ import { useRef } from "react";
11
+
12
+ export default {
13
+ title: "GridForm / Samples",
14
+ component: GridFormDropDown,
15
+ args: {},
16
+ } as ComponentMeta<typeof GridFormDropDown>;
17
+
18
+ const Template: ComponentStory<typeof GridFormDropDown> = (props) => {
19
+ const anchorRef1 = useRef<HTMLHeadingElement>(null);
20
+ const anchorRef2 = useRef<HTMLHeadingElement>(null);
21
+ const anchorRef3 = useRef<HTMLHeadingElement>(null);
22
+
23
+ return (
24
+ <div className={"react-menu-inline-test"}>
25
+ <GridContextProvider>
26
+ <h6 ref={anchorRef1}>No options</h6>
27
+ <GridPopoverContext.Provider value={{ anchorRef: anchorRef1 } as any as GridPopoverContextType<any>}>
28
+ <GridFormDropDown {...props} options={[]} />
29
+ </GridPopoverContext.Provider>
30
+
31
+ <h6 ref={anchorRef2}>Enabled and disabled</h6>
32
+ <GridPopoverContext.Provider value={{ anchorRef: anchorRef2 } as any as GridPopoverContextType<any>}>
33
+ <GridFormDropDown
34
+ {...props}
35
+ options={[
36
+ { label: "Enabled", value: 1 },
37
+ { label: "Disabled", value: 0, disabled: true },
38
+ ]}
39
+ />
40
+ </GridPopoverContext.Provider>
41
+
42
+ <h6 ref={anchorRef3}>Headers</h6>
43
+ <GridPopoverContext.Provider value={{ anchorRef: anchorRef3 } as any as GridPopoverContextType<any>}>
44
+ <GridFormDropDown
45
+ {...props}
46
+ options={[
47
+ MenuHeaderItem("Header 1"),
48
+ { label: "Option 1", value: 1 },
49
+ MenuHeaderItem("Header 2"),
50
+ { label: "Option 2", value: 2 },
51
+ ]}
52
+ />
53
+ </GridPopoverContext.Provider>
54
+ </GridContextProvider>
55
+ </div>
56
+ );
57
+ };
58
+
59
+ export const GridFormDropDown_ = Template.bind({});
60
+ GridFormDropDown_.args = { options: [] };
@@ -0,0 +1,56 @@
1
+ import "@linzjs/lui/dist/scss/base.scss";
2
+ import "@linzjs/lui/dist/fonts";
3
+ // Force react-menu not to render static inline not absolute
4
+ import "./reactMenuTest.scss";
5
+
6
+ import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
7
+ import { GridFormEditBearing } from "../../../components/gridForm/GridFormEditBearing";
8
+ import { GridContextProvider } from "../../../contexts/GridContextProvider";
9
+ import { GridPopoverContext, GridPopoverContextType } from "contexts/GridPopoverContext";
10
+ import { useRef } from "react";
11
+ import { GridPopoverEditBearingEditorParams } from "../../../components/gridPopoverEdit/GridPopoverEditBearing";
12
+
13
+ export default {
14
+ title: "GridForm / Samples",
15
+ component: GridFormEditBearing,
16
+ args: {},
17
+ } as ComponentMeta<typeof GridFormEditBearing>;
18
+
19
+ const Template: ComponentStory<typeof GridFormEditBearing> = (props) => {
20
+ const values = [
21
+ ["Null value", null],
22
+ ["Minimum value", 0],
23
+ ["Maximum value", 359.59599],
24
+ ["5dp value", 1.23456],
25
+ ["Invalid 6dp value", 1.234567],
26
+ ["Invalid exceeds max value", 360],
27
+ ["Invalid exceeds min value", -0.00001],
28
+ ];
29
+ // eslint-disable-next-line react-hooks/rules-of-hooks
30
+ const anchorRefs = values.map(() => useRef<HTMLHeadingElement>(null));
31
+
32
+ return (
33
+ <div className={"react-menu-inline-test"}>
34
+ <GridContextProvider>
35
+ {values.map((value, index) => (
36
+ <>
37
+ <h6 ref={anchorRefs[index]}>{value[0]}</h6>
38
+ <GridPopoverContext.Provider
39
+ value={
40
+ {
41
+ anchorRef: anchorRefs[index],
42
+ value: value[1],
43
+ } as any as GridPopoverContextType<any>
44
+ }
45
+ >
46
+ <GridFormEditBearing {...props} {...GridPopoverEditBearingEditorParams} />
47
+ </GridPopoverContext.Provider>
48
+ </>
49
+ ))}
50
+ </GridContextProvider>
51
+ </div>
52
+ );
53
+ };
54
+
55
+ export const GridFormEditBearing_ = Template.bind({});
56
+ GridFormEditBearing_.args = {};