@linzjs/step-ag-grid 8.1.0 → 8.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.
- package/dist/index.css +19 -5
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +2 -2
- package/dist/src/components/gridForm/GridFormMultiSelect.d.ts +1 -0
- package/dist/src/components/gridPopoverEdit/GridPopoverEditDropDown.d.ts +2 -2
- package/dist/src/utils/bearing.d.ts +2 -0
- package/dist/step-ag-grid.esm.js +39 -36
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/GridCell.tsx +2 -2
- package/src/components/gridForm/GridFormDropDown.tsx +8 -4
- package/src/components/gridForm/GridFormEditBearing.tsx +1 -1
- package/src/components/gridForm/GridFormMultiSelect.tsx +10 -8
- package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +8 -13
- package/src/components/gridPopoverEdit/GridPopoverEditDropDown.ts +3 -3
- package/src/react-menu3/styles/_var.scss +1 -1
- package/src/stories/grid/gridForm/GridFormDropDown.stories.tsx +2 -6
- package/src/stories/grid/gridForm/GridFormEditBearing.stories.tsx +8 -12
- package/src/stories/grid/gridForm/GridFormEditBearingCorrection.stories.tsx +8 -12
- package/src/stories/grid/gridForm/GridFormMessage.stories.tsx +0 -1
- package/src/stories/grid/gridForm/GridFormMultiSelect.stories.tsx +70 -0
- package/src/stories/grid/gridForm/GridFormTextArea.stories.tsx +44 -0
- package/src/stories/grid/gridForm/GridFormTextInput.stories.tsx +44 -0
- package/src/styles/Grid.scss +1 -1
- package/src/styles/GridFormMultiSelect.scss +4 -0
- package/src/styles/GridIcon.scss +10 -0
- package/src/styles/lui-overrides.scss +1 -1
- package/src/styles/react-menu-customisations.scss +2 -2
- package/src/utils/bearing.test.ts +46 -3
- package/src/utils/bearing.ts +14 -0
package/package.json
CHANGED
|
@@ -29,8 +29,8 @@ export const GridCellRenderer = (props: ICellRendererParams) => {
|
|
|
29
29
|
return (
|
|
30
30
|
<GridLoadableCell isLoading={checkUpdating(colDef.field ?? colDef.colId ?? "", props.data.id)}>
|
|
31
31
|
<>
|
|
32
|
-
{typeof warningText === "string" && <GridIcon icon={"
|
|
33
|
-
{typeof infoText === "string" && <GridIcon icon={"
|
|
32
|
+
{typeof warningText === "string" && <GridIcon icon={"ic_warning_outline"} title={warningText} />}
|
|
33
|
+
{typeof infoText === "string" && <GridIcon icon={"ic_info_outline"} title={infoText} />}
|
|
34
34
|
<div style={{ display: "flex", flex: 1, overflow: "hidden" }}>
|
|
35
35
|
{colDef?.cellRendererParams?.originalCellRenderer ? (
|
|
36
36
|
<colDef.cellRendererParams.originalCellRenderer {...props} />
|
|
@@ -36,7 +36,7 @@ export const MenuHeaderItem = (title: string) => {
|
|
|
36
36
|
|
|
37
37
|
export type SelectOption = null | string | FinalSelectOption;
|
|
38
38
|
|
|
39
|
-
export interface
|
|
39
|
+
export interface GridFormDropDownProps<RowType extends GridBaseRow> extends CellEditorCommon {
|
|
40
40
|
// This overrides CellEditorCommon to provide some common class options
|
|
41
41
|
className?:
|
|
42
42
|
| "GridPopoverEditDropDown-containerSmall"
|
|
@@ -63,7 +63,7 @@ const fieldToString = (field: any) => {
|
|
|
63
63
|
return typeof field == "symbol" ? field.toString() : `${field}`;
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
export const GridFormDropDown = <RowType extends GridBaseRow>(props:
|
|
66
|
+
export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormDropDownProps<RowType>) => {
|
|
67
67
|
const { selectedRows, field, data } = useGridPopoverContext<RowType>();
|
|
68
68
|
|
|
69
69
|
// Save triggers during async action processing which triggers another selectItem(), this ref blocks that
|
|
@@ -215,7 +215,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
215
215
|
className={"LuiTextInput-input"}
|
|
216
216
|
ref={ref}
|
|
217
217
|
type="text"
|
|
218
|
-
placeholder={props.filterPlaceholder ?? "
|
|
218
|
+
placeholder={props.filterPlaceholder ?? "Filter..."}
|
|
219
219
|
data-testid={"filteredMenu-free-text-input"}
|
|
220
220
|
defaultValue={filter}
|
|
221
221
|
data-allowtabtosave={true}
|
|
@@ -237,7 +237,11 @@ export const GridFormDropDown = <RowType extends GridBaseRow>(props: GridFormPop
|
|
|
237
237
|
<ComponentLoadingWrapper loading={!options} className={"GridFormDropDown-options"}>
|
|
238
238
|
<>
|
|
239
239
|
{options && (isEmpty(options) || (filteredValues && isEmpty(filteredValues))) && (
|
|
240
|
-
<MenuItem
|
|
240
|
+
<MenuItem
|
|
241
|
+
key={`${fieldToString(field)}-empty`}
|
|
242
|
+
className={"GridPopoverEditDropDown-noOptions"}
|
|
243
|
+
disabled={true}
|
|
244
|
+
>
|
|
241
245
|
{props.noOptionsMessage ?? "No Options"}
|
|
242
246
|
</MenuItem>
|
|
243
247
|
)}
|
|
@@ -56,7 +56,7 @@ export const GridFormEditBearing = <RowType extends GridBaseRow>(props: GridForm
|
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
return popoverWrapper(
|
|
59
|
-
<div className={"GridFormEditBearing-input
|
|
59
|
+
<div className={"GridFormEditBearing-input"}>
|
|
60
60
|
<TextInputFormatted
|
|
61
61
|
value={defaultValue}
|
|
62
62
|
onChange={(e) => {
|
|
@@ -52,6 +52,7 @@ 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
|
+
noOptionsMessage?: string;
|
|
55
56
|
onSelectFilter?: (props: { filter: string; options: MultiSelectOption[] }) => void;
|
|
56
57
|
onSave?: (props: { selectedRows: RowType[]; selectedOptions: MultiSelectOption[] }) => Promise<boolean>;
|
|
57
58
|
headers?: GridFormMultiSelectGroup[];
|
|
@@ -117,7 +118,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
|
|
|
117
118
|
const headerGroups = useMemo(() => {
|
|
118
119
|
if (!options) return undefined;
|
|
119
120
|
const result = groupBy(
|
|
120
|
-
options.filter((o) => textMatch(o.label, filter) && o.value),
|
|
121
|
+
options.filter((o) => textMatch(o.label, filter) && o.value != null),
|
|
121
122
|
"filter",
|
|
122
123
|
);
|
|
123
124
|
// remove leading/trailing/duplicate dividers
|
|
@@ -163,8 +164,12 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow>(props: GridForm
|
|
|
163
164
|
filterPlaceholder={props.filterPlaceholder}
|
|
164
165
|
/>
|
|
165
166
|
)}
|
|
166
|
-
|
|
167
|
-
|
|
167
|
+
{headerGroups && (isEmpty(headerGroups) || !toPairs(headerGroups).some(([_, options]) => !isEmpty(options))) && (
|
|
168
|
+
<MenuItem key={"noOptions"} className={"GridMultiSelect-noOptions"} disabled={true}>
|
|
169
|
+
{props.noOptionsMessage ?? "No Options"}
|
|
170
|
+
</MenuItem>
|
|
171
|
+
)}
|
|
172
|
+
{headerGroups && !isEmpty(headerGroups) && (
|
|
168
173
|
<div className={"GridFormMultiSelect-options"}>
|
|
169
174
|
{headers.map((header, index) => {
|
|
170
175
|
const subOptions = headerGroups[`${header.filter}`];
|
|
@@ -307,7 +312,7 @@ const FilterInput = (props: {
|
|
|
307
312
|
<input
|
|
308
313
|
className={"LuiTextInput-input"}
|
|
309
314
|
type="text"
|
|
310
|
-
placeholder={filterPlaceholder ?? "
|
|
315
|
+
placeholder={filterPlaceholder ?? "Filter..."}
|
|
311
316
|
data-testid={"filteredMenu-free-text-input"}
|
|
312
317
|
value={filter}
|
|
313
318
|
data-disableenterautosave={true}
|
|
@@ -328,9 +333,6 @@ const FilterInput = (props: {
|
|
|
328
333
|
)}
|
|
329
334
|
</FocusableItem>
|
|
330
335
|
<MenuDivider key={`$$divider_filter`} />
|
|
331
|
-
{headerGroups && !toPairs(headerGroups).some(([_, options]) => !isEmpty(options)) && (
|
|
332
|
-
<div className={"szh-menu__item GridPopoverEditDropDown-noOptions"}>No Options</div>
|
|
333
|
-
)}
|
|
334
336
|
</>
|
|
335
337
|
);
|
|
336
338
|
};
|
|
@@ -365,7 +367,7 @@ const MenuRadioItem = (props: {
|
|
|
365
367
|
value={`${item.value}`}
|
|
366
368
|
label={
|
|
367
369
|
<>
|
|
368
|
-
{item.warning && <GridIcon icon={"
|
|
370
|
+
{item.warning && <GridIcon icon={"ic_warning_outline"} title={item.warning} />}
|
|
369
371
|
{item.label ?? (item.value == null ? `<${item.value}>` : `${item.value}`)}
|
|
370
372
|
</>
|
|
371
373
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
bearingCorrectionRangeValidator,
|
|
3
|
+
bearingCorrectionValueFormatter,
|
|
4
|
+
bearingRangeValidator,
|
|
5
|
+
bearingValueFormatter,
|
|
6
|
+
} from "../../utils/bearing";
|
|
2
7
|
import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
|
|
3
8
|
import { GridFormEditBearing, GridFormEditBearingProps } from "../gridForm/GridFormEditBearing";
|
|
4
9
|
import { GridBaseRow } from "../Grid";
|
|
@@ -27,12 +32,7 @@ const GridPopoverEditBearingLike = <RowType extends GridBaseRow>(
|
|
|
27
32
|
export const GridPopoverEditBearingEditorParams = {
|
|
28
33
|
placeHolder: "Enter bearing",
|
|
29
34
|
formatValue: bearingValueFormatter,
|
|
30
|
-
range:
|
|
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
|
-
},
|
|
35
|
+
range: bearingRangeValidator,
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
export const GridPopoverEditBearing = <RowType extends GridBaseRow>(
|
|
@@ -50,12 +50,7 @@ export const GridPopoverEditBearing = <RowType extends GridBaseRow>(
|
|
|
50
50
|
export const GridPopoverEditBearingCorrectionEditorParams = {
|
|
51
51
|
placeHolder: "Enter bearing correction",
|
|
52
52
|
formatValue: bearingCorrectionValueFormatter,
|
|
53
|
-
range:
|
|
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
|
-
},
|
|
53
|
+
range: bearingCorrectionRangeValidator,
|
|
59
54
|
};
|
|
60
55
|
|
|
61
56
|
export const GridPopoverEditBearingCorrection = <RowType extends GridBaseRow>(
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ColDefT, GenericCellEditorProps, GridCell } from "../GridCell";
|
|
2
2
|
import { GridBaseRow } from "../Grid";
|
|
3
|
-
import { GridFormDropDown,
|
|
3
|
+
import { GridFormDropDown, GridFormDropDownProps } from "../gridForm/GridFormDropDown";
|
|
4
4
|
import { GenericCellColDef } from "../gridRender/GridRenderGenericCell";
|
|
5
5
|
|
|
6
6
|
export const GridPopoverEditDropDown = <RowType extends GridBaseRow>(
|
|
7
7
|
colDef: GenericCellColDef<RowType>,
|
|
8
|
-
props: GenericCellEditorProps<
|
|
8
|
+
props: GenericCellEditorProps<GridFormDropDownProps<RowType>>,
|
|
9
9
|
): ColDefT<RowType> =>
|
|
10
10
|
GridCell(colDef, {
|
|
11
11
|
editor: GridFormDropDown,
|
|
@@ -13,6 +13,6 @@ export const GridPopoverEditDropDown = <RowType extends GridBaseRow>(
|
|
|
13
13
|
editorParams: {
|
|
14
14
|
// Defaults to large size container
|
|
15
15
|
className: "GridPopoverEditDropDown-containerLarge",
|
|
16
|
-
...(props.editorParams as
|
|
16
|
+
...(props.editorParams as GridFormDropDownProps<RowType>),
|
|
17
17
|
},
|
|
18
18
|
});
|
|
@@ -2,11 +2,7 @@ import "@linzjs/lui/dist/scss/base.scss";
|
|
|
2
2
|
import "@linzjs/lui/dist/fonts";
|
|
3
3
|
|
|
4
4
|
import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
|
|
5
|
-
import {
|
|
6
|
-
GridFormDropDown,
|
|
7
|
-
GridFormPopoutDropDownProps,
|
|
8
|
-
MenuHeaderItem,
|
|
9
|
-
} from "../../../components/gridForm/GridFormDropDown";
|
|
5
|
+
import { GridFormDropDown, GridFormDropDownProps, MenuHeaderItem } from "../../../components/gridForm/GridFormDropDown";
|
|
10
6
|
import { GridContextProvider } from "../../../contexts/GridContextProvider";
|
|
11
7
|
import { GridPopoverContext, GridPopoverContextType } from "contexts/GridPopoverContext";
|
|
12
8
|
import { useRef } from "react";
|
|
@@ -19,7 +15,7 @@ export default {
|
|
|
19
15
|
} as ComponentMeta<typeof GridFormDropDown>;
|
|
20
16
|
|
|
21
17
|
const Template: ComponentStory<typeof GridFormDropDown> = (props) => {
|
|
22
|
-
const configs: [string,
|
|
18
|
+
const configs: [string, GridFormDropDownProps<GridBaseRow>, string?][] = [
|
|
23
19
|
["No options", { options: [] }],
|
|
24
20
|
["Custom no options", { options: [], noOptionsMessage: "Custom no options" }],
|
|
25
21
|
[
|
|
@@ -2,7 +2,7 @@ import "@linzjs/lui/dist/scss/base.scss";
|
|
|
2
2
|
import "@linzjs/lui/dist/fonts";
|
|
3
3
|
|
|
4
4
|
import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
|
|
5
|
-
import { GridFormEditBearing } from "../../../components/gridForm/GridFormEditBearing";
|
|
5
|
+
import { GridFormEditBearing, GridFormEditBearingProps } from "../../../components/gridForm/GridFormEditBearing";
|
|
6
6
|
import { GridContextProvider } from "../../../contexts/GridContextProvider";
|
|
7
7
|
import { GridPopoverContext, GridPopoverContextType } from "contexts/GridPopoverContext";
|
|
8
8
|
import { useRef } from "react";
|
|
@@ -15,14 +15,11 @@ export default {
|
|
|
15
15
|
} as ComponentMeta<typeof GridFormEditBearing>;
|
|
16
16
|
|
|
17
17
|
const Template: ComponentStory<typeof GridFormEditBearing> = (props) => {
|
|
18
|
-
const values = [
|
|
19
|
-
["Null value", null],
|
|
20
|
-
["
|
|
21
|
-
["
|
|
22
|
-
["
|
|
23
|
-
["Invalid 6dp value", 1.234567],
|
|
24
|
-
["Invalid exceeds max value", 360],
|
|
25
|
-
["Invalid exceeds min value", -0.00001],
|
|
18
|
+
const values: [string, GridFormEditBearingProps<any>, number | null][] = [
|
|
19
|
+
["Null value", {}, null],
|
|
20
|
+
["Custom placeholder", { placeHolder: "Custom placeholder" }, null],
|
|
21
|
+
["Valid value", {}, 90],
|
|
22
|
+
["With error", {}, 1.234567],
|
|
26
23
|
];
|
|
27
24
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
28
25
|
const anchorRefs = values.map(() => useRef<HTMLHeadingElement>(null));
|
|
@@ -37,11 +34,11 @@ const Template: ComponentStory<typeof GridFormEditBearing> = (props) => {
|
|
|
37
34
|
value={
|
|
38
35
|
{
|
|
39
36
|
anchorRef: anchorRefs[index],
|
|
40
|
-
value: value[
|
|
37
|
+
value: value[2],
|
|
41
38
|
} as any as GridPopoverContextType<any>
|
|
42
39
|
}
|
|
43
40
|
>
|
|
44
|
-
<GridFormEditBearing {...props} {...GridPopoverEditBearingEditorParams} />
|
|
41
|
+
<GridFormEditBearing {...props} {...GridPopoverEditBearingEditorParams} {...value[1]} />
|
|
45
42
|
</GridPopoverContext.Provider>
|
|
46
43
|
</>
|
|
47
44
|
))}
|
|
@@ -51,4 +48,3 @@ const Template: ComponentStory<typeof GridFormEditBearing> = (props) => {
|
|
|
51
48
|
};
|
|
52
49
|
|
|
53
50
|
export const GridFormEditBearing_ = Template.bind({});
|
|
54
|
-
GridFormEditBearing_.args = {};
|
|
@@ -2,7 +2,7 @@ import "@linzjs/lui/dist/scss/base.scss";
|
|
|
2
2
|
import "@linzjs/lui/dist/fonts";
|
|
3
3
|
|
|
4
4
|
import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
|
|
5
|
-
import { GridFormEditBearing } from "../../../components/gridForm/GridFormEditBearing";
|
|
5
|
+
import { GridFormEditBearing, GridFormEditBearingProps } from "../../../components/gridForm/GridFormEditBearing";
|
|
6
6
|
import { GridContextProvider } from "../../../contexts/GridContextProvider";
|
|
7
7
|
import { GridPopoverContext, GridPopoverContextType } from "contexts/GridPopoverContext";
|
|
8
8
|
import { useRef } from "react";
|
|
@@ -15,14 +15,11 @@ export default {
|
|
|
15
15
|
} as ComponentMeta<typeof GridFormEditBearing>;
|
|
16
16
|
|
|
17
17
|
const Template: ComponentStory<typeof GridFormEditBearing> = (props) => {
|
|
18
|
-
const values = [
|
|
19
|
-
["Null value", null],
|
|
20
|
-
["
|
|
21
|
-
["
|
|
22
|
-
["
|
|
23
|
-
["Invalid 6dp value", 1.234567],
|
|
24
|
-
["Invalid exceeds max value", 360],
|
|
25
|
-
["Invalid exceeds min value", -180],
|
|
18
|
+
const values: [string, GridFormEditBearingProps<any>, number | null][] = [
|
|
19
|
+
["Null value", {}, null],
|
|
20
|
+
["Custom placeholder", { placeHolder: "Custom placeholder" }, null],
|
|
21
|
+
["Valid value", {}, -10],
|
|
22
|
+
["With error", {}, 360],
|
|
26
23
|
];
|
|
27
24
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
28
25
|
const anchorRefs = values.map(() => useRef<HTMLHeadingElement>(null));
|
|
@@ -37,11 +34,11 @@ const Template: ComponentStory<typeof GridFormEditBearing> = (props) => {
|
|
|
37
34
|
value={
|
|
38
35
|
{
|
|
39
36
|
anchorRef: anchorRefs[index],
|
|
40
|
-
value: value[
|
|
37
|
+
value: value[2],
|
|
41
38
|
} as any as GridPopoverContextType<any>
|
|
42
39
|
}
|
|
43
40
|
>
|
|
44
|
-
<GridFormEditBearing {...props} {...GridPopoverEditBearingCorrectionEditorParams} />
|
|
41
|
+
<GridFormEditBearing {...props} {...GridPopoverEditBearingCorrectionEditorParams} {...value[1]} />
|
|
45
42
|
</GridPopoverContext.Provider>
|
|
46
43
|
</>
|
|
47
44
|
))}
|
|
@@ -51,4 +48,3 @@ const Template: ComponentStory<typeof GridFormEditBearing> = (props) => {
|
|
|
51
48
|
};
|
|
52
49
|
|
|
53
50
|
export const GridFormEditBearingCorrection_ = Template.bind({});
|
|
54
|
-
GridFormEditBearingCorrection_.args = {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import "@linzjs/lui/dist/scss/base.scss";
|
|
2
|
+
import "@linzjs/lui/dist/fonts";
|
|
3
|
+
|
|
4
|
+
import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
|
|
5
|
+
import { GridFormMultiSelect, GridFormMultiSelectProps } from "../../../components/gridForm/GridFormMultiSelect";
|
|
6
|
+
import { GridContextProvider } from "../../../contexts/GridContextProvider";
|
|
7
|
+
import { GridPopoverContext, GridPopoverContextType } from "contexts/GridPopoverContext";
|
|
8
|
+
import { useRef } from "react";
|
|
9
|
+
import { GridBaseRow } from "../../../components/Grid";
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
title: "GridForm / Testing",
|
|
13
|
+
component: GridFormMultiSelect,
|
|
14
|
+
args: {},
|
|
15
|
+
} as ComponentMeta<typeof GridFormMultiSelect>;
|
|
16
|
+
|
|
17
|
+
const Template: ComponentStory<typeof GridFormMultiSelect> = (props) => {
|
|
18
|
+
const configs: [string, GridFormMultiSelectProps<GridBaseRow>, string?][] = [
|
|
19
|
+
["No options", { options: [] }],
|
|
20
|
+
["Custom no options", { options: [], noOptionsMessage: "Custom no options" }],
|
|
21
|
+
[
|
|
22
|
+
"With options",
|
|
23
|
+
{
|
|
24
|
+
options: [
|
|
25
|
+
{ label: "One", value: 0 },
|
|
26
|
+
{ label: "Two", value: 1 },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
[
|
|
31
|
+
"With filter",
|
|
32
|
+
{
|
|
33
|
+
filtered: true,
|
|
34
|
+
options: [
|
|
35
|
+
{ label: "One", value: 0 },
|
|
36
|
+
{ label: "With warning", value: 1, warning: "Test warning" },
|
|
37
|
+
{ label: "Three", value: 2 },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
];
|
|
42
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
43
|
+
const anchorRefs = configs.map(() => useRef<HTMLHeadingElement>(null));
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div className={"react-menu-inline-test"}>
|
|
47
|
+
<GridContextProvider>
|
|
48
|
+
{configs.map((config, index) => (
|
|
49
|
+
<div key={`${index}`}>
|
|
50
|
+
<h6 ref={anchorRefs[index]}>{config[0]}</h6>
|
|
51
|
+
<GridPopoverContext.Provider
|
|
52
|
+
value={
|
|
53
|
+
{
|
|
54
|
+
anchorRef: anchorRefs[index],
|
|
55
|
+
data: { value: config[2] },
|
|
56
|
+
value: config[2],
|
|
57
|
+
field: "value",
|
|
58
|
+
} as any as GridPopoverContextType<any>
|
|
59
|
+
}
|
|
60
|
+
>
|
|
61
|
+
<GridFormMultiSelect {...props} {...config[1]} />
|
|
62
|
+
</GridPopoverContext.Provider>
|
|
63
|
+
</div>
|
|
64
|
+
))}
|
|
65
|
+
</GridContextProvider>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const GridFormMultiSelect_ = Template.bind({});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import "@linzjs/lui/dist/scss/base.scss";
|
|
2
|
+
import "@linzjs/lui/dist/fonts";
|
|
3
|
+
|
|
4
|
+
import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
|
|
5
|
+
import { GridFormTextArea, GridFormTextAreaProps } from "../../../components/gridForm/GridFormTextArea";
|
|
6
|
+
import { GridContextProvider } from "../../../contexts/GridContextProvider";
|
|
7
|
+
import { GridPopoverContext, GridPopoverContextType } from "contexts/GridPopoverContext";
|
|
8
|
+
import { useRef } from "react";
|
|
9
|
+
import { GridBaseRow } from "../../../components/Grid";
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
title: "GridForm / Testing",
|
|
13
|
+
component: GridFormTextArea,
|
|
14
|
+
args: {},
|
|
15
|
+
} as ComponentMeta<typeof GridFormTextArea>;
|
|
16
|
+
|
|
17
|
+
const Template: ComponentStory<typeof GridFormTextArea> = (props) => {
|
|
18
|
+
const configs: [string, GridFormTextAreaProps<GridBaseRow>, string?][] = [
|
|
19
|
+
["Text area", {}],
|
|
20
|
+
["Text area with text", {}, "Some text"],
|
|
21
|
+
["Text area with error & placeholder", { required: true, placeholder: "Custom placeholder" }],
|
|
22
|
+
];
|
|
23
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
24
|
+
const anchorRefs = configs.map(() => useRef<HTMLHeadingElement>(null));
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div className={"react-menu-inline-test"}>
|
|
28
|
+
<GridContextProvider>
|
|
29
|
+
{configs.map((config, index) => (
|
|
30
|
+
<>
|
|
31
|
+
<h6 ref={anchorRefs[index]}>{config[0]}</h6>
|
|
32
|
+
<GridPopoverContext.Provider
|
|
33
|
+
value={{ anchorRef: anchorRefs[index], value: config[2] } as any as GridPopoverContextType<any>}
|
|
34
|
+
>
|
|
35
|
+
<GridFormTextArea {...props} {...config[1]} />
|
|
36
|
+
</GridPopoverContext.Provider>
|
|
37
|
+
</>
|
|
38
|
+
))}
|
|
39
|
+
</GridContextProvider>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const GridFormTextArea_ = Template.bind({});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import "@linzjs/lui/dist/scss/base.scss";
|
|
2
|
+
import "@linzjs/lui/dist/fonts";
|
|
3
|
+
|
|
4
|
+
import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
|
|
5
|
+
import { GridFormTextInput, GridFormTextInputProps } from "../../../components/gridForm/GridFormTextInput";
|
|
6
|
+
import { GridContextProvider } from "../../../contexts/GridContextProvider";
|
|
7
|
+
import { GridPopoverContext, GridPopoverContextType } from "contexts/GridPopoverContext";
|
|
8
|
+
import { useRef } from "react";
|
|
9
|
+
import { GridBaseRow } from "../../../components/Grid";
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
title: "GridForm / Testing",
|
|
13
|
+
component: GridFormTextInput,
|
|
14
|
+
args: {},
|
|
15
|
+
} as ComponentMeta<typeof GridFormTextInput>;
|
|
16
|
+
|
|
17
|
+
const Template: ComponentStory<typeof GridFormTextInput> = (props) => {
|
|
18
|
+
const configs: [string, GridFormTextInputProps<GridBaseRow>, string?][] = [
|
|
19
|
+
["Text input", {}],
|
|
20
|
+
["Text input with text", {}, "Some text"],
|
|
21
|
+
["Text input with error & placeholder", { required: true, placeholder: "Custom placeholder" }],
|
|
22
|
+
];
|
|
23
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
24
|
+
const anchorRefs = configs.map(() => useRef<HTMLHeadingElement>(null));
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div className={"react-menu-inline-test"}>
|
|
28
|
+
<GridContextProvider>
|
|
29
|
+
{configs.map((config, index) => (
|
|
30
|
+
<>
|
|
31
|
+
<h6 ref={anchorRefs[index]}>{config[0]}</h6>
|
|
32
|
+
<GridPopoverContext.Provider
|
|
33
|
+
value={{ anchorRef: anchorRefs[index], value: config[2] } as any as GridPopoverContextType<any>}
|
|
34
|
+
>
|
|
35
|
+
<GridFormTextInput {...props} {...config[1]} />
|
|
36
|
+
</GridPopoverContext.Provider>
|
|
37
|
+
</>
|
|
38
|
+
))}
|
|
39
|
+
</GridContextProvider>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const GridFormTextInput_ = Template.bind({});
|
package/src/styles/Grid.scss
CHANGED
package/src/styles/GridIcon.scss
CHANGED
|
@@ -9,11 +9,21 @@
|
|
|
9
9
|
fill: colors.$info;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
.AgGridGenericCellRenderer-ic_info_outlineIcon {
|
|
13
|
+
margin-right: 4px;
|
|
14
|
+
fill: colors.$info;
|
|
15
|
+
}
|
|
16
|
+
|
|
12
17
|
.AgGridGenericCellRenderer-ic_warningIcon {
|
|
13
18
|
margin-right: 4px;
|
|
14
19
|
fill: colors.$warning;
|
|
15
20
|
}
|
|
16
21
|
|
|
22
|
+
.AgGridGenericCellRenderer-ic_warning_outlineIcon {
|
|
23
|
+
margin-right: 4px;
|
|
24
|
+
fill: colors.$warning;
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
.GridIcon-disabled {
|
|
18
28
|
fill: colors.$silver !important;
|
|
19
29
|
}
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
.step-ag-grid-react-menu.szh-menu {
|
|
10
10
|
z-index: 900;
|
|
11
11
|
color: colors.$base-type-color;
|
|
12
|
-
@include fonts.font-
|
|
12
|
+
@include fonts.font-regular();
|
|
13
13
|
|
|
14
14
|
div,
|
|
15
15
|
a[role="menuitem"] {
|
|
16
16
|
text-decoration: none;
|
|
17
17
|
color: colors.$base-type-color;
|
|
18
|
-
@include fonts.font-
|
|
18
|
+
@include fonts.font-regular();
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
li[role="menuitem"]:hover {
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
bearingCorrectionRangeValidator,
|
|
3
|
+
bearingRangeValidator,
|
|
4
|
+
bearingStringValidator,
|
|
5
|
+
convertDDToDMS,
|
|
6
|
+
} from "./bearing";
|
|
2
7
|
|
|
3
|
-
describe("
|
|
4
|
-
test("converts decimal-ish degrees to DMS", () => {
|
|
8
|
+
describe("bearing", () => {
|
|
9
|
+
test("convertDDToDMS converts decimal-ish degrees to DMS", () => {
|
|
5
10
|
expect(convertDDToDMS(-0.001, false, false)).toBe("-0° 00' 10\"");
|
|
6
11
|
expect(convertDDToDMS(-10.001, false, false)).toBe("-10° 00' 10\"");
|
|
7
12
|
expect(convertDDToDMS(-370.001, false, false)).toBe("-10° 00' 10\"");
|
|
@@ -27,4 +32,42 @@ describe("convertDDToDMS", () => {
|
|
|
27
32
|
expect(convertDDToDMS(300.1, false, false)).toBe("300° 10'");
|
|
28
33
|
expect(convertDDToDMS(0, false)).toBe("0° 00'");
|
|
29
34
|
});
|
|
35
|
+
|
|
36
|
+
test("bearingStringValidator", () => {
|
|
37
|
+
const tests: [string, string | null][] = [
|
|
38
|
+
["", null],
|
|
39
|
+
["1", null],
|
|
40
|
+
["1.2345", null],
|
|
41
|
+
["-1.2345", null],
|
|
42
|
+
["360.2345", null],
|
|
43
|
+
["-360.2345", null],
|
|
44
|
+
["1.2e6", "Bearing must be a number in D.MMSSS format"],
|
|
45
|
+
["0.60000", "Bearing must be a number in D.MMSSS format"],
|
|
46
|
+
["0.00600", "Bearing must be a number in D.MMSSS format"],
|
|
47
|
+
["0.123456", "Bearing has a maximum of 5 decimal places"],
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
tests.forEach((test, i) => {
|
|
51
|
+
expect(bearingStringValidator(test[0]), `Test ${i}: "${test[0]}" should return "${test[1]}"`).toBe(test[1]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// calls custom invalid
|
|
55
|
+
const fn = jest.fn();
|
|
56
|
+
bearingStringValidator("1.2", fn);
|
|
57
|
+
expect(fn).toHaveBeenCalledWith(1.2);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("bearingRangeValidator", () => {
|
|
61
|
+
expect(bearingRangeValidator(0)).toBeNull();
|
|
62
|
+
expect(bearingRangeValidator(359.595999)).toBeNull();
|
|
63
|
+
expect(bearingRangeValidator(-0.00001)).toBe("Bearing must not be negative");
|
|
64
|
+
expect(bearingRangeValidator(360)).toBe("Bearing must be less than 360 degrees");
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("bearingCorrectionRangeValidator", () => {
|
|
68
|
+
expect(bearingCorrectionRangeValidator(-179.59999)).toBeNull();
|
|
69
|
+
expect(bearingCorrectionRangeValidator(359.59999)).toBeNull();
|
|
70
|
+
expect(bearingCorrectionRangeValidator(-180)).toBe("Bearing correction must be greater then -180 degrees");
|
|
71
|
+
expect(bearingCorrectionRangeValidator(360)).toBe("Bearing correction must be less than 360 degrees");
|
|
72
|
+
});
|
|
30
73
|
});
|
package/src/utils/bearing.ts
CHANGED
|
@@ -81,3 +81,17 @@ export const convertDDToDMS = (dd: number | null, showPositiveSymbol = true, add
|
|
|
81
81
|
|
|
82
82
|
return dmsString;
|
|
83
83
|
};
|
|
84
|
+
|
|
85
|
+
export const bearingRangeValidator = (value: number | null) => {
|
|
86
|
+
if (value === null) return "Bearing is required";
|
|
87
|
+
if (value >= 360) return "Bearing must be less than 360 degrees";
|
|
88
|
+
if (value < 0) return "Bearing must not be negative";
|
|
89
|
+
return null;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const bearingCorrectionRangeValidator = (value: number | null) => {
|
|
93
|
+
if (value === null) return "Bearing correction is required";
|
|
94
|
+
if (value >= 360) return "Bearing correction must be less than 360 degrees";
|
|
95
|
+
if (value <= -180) return "Bearing correction must be greater then -180 degrees";
|
|
96
|
+
return null;
|
|
97
|
+
};
|