@etsoo/materialui 1.3.63 → 1.3.65
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/__tests__/CustomFields.tsx +93 -0
- package/lib/custom/CustomFieldUtils.d.ts +50 -0
- package/lib/custom/CustomFieldUtils.js +138 -0
- package/lib/custom/FieldAmountLabel.d.ts +7 -0
- package/lib/custom/FieldAmountLabel.js +40 -0
- package/lib/custom/FieldCheckbox.d.ts +8 -0
- package/lib/custom/FieldCheckbox.js +49 -0
- package/lib/custom/FieldCombobox.d.ts +8 -0
- package/lib/custom/FieldCombobox.js +40 -0
- package/lib/custom/FieldDateInput.d.ts +7 -0
- package/lib/custom/FieldDateInput.js +43 -0
- package/lib/custom/FieldDivider.d.ts +7 -0
- package/lib/custom/FieldDivider.js +12 -0
- package/lib/custom/FieldInput.d.ts +7 -0
- package/lib/custom/FieldInput.js +27 -0
- package/lib/custom/FieldJson.d.ts +7 -0
- package/lib/custom/FieldJson.js +50 -0
- package/lib/custom/FieldLabel.d.ts +7 -0
- package/lib/custom/FieldLabel.js +28 -0
- package/lib/custom/FieldNumberInput.d.ts +7 -0
- package/lib/custom/FieldNumberInput.js +37 -0
- package/lib/custom/FieldRadio.d.ts +8 -0
- package/lib/custom/FieldRadio.js +49 -0
- package/lib/custom/FieldSelect.d.ts +8 -0
- package/lib/custom/FieldSelect.js +48 -0
- package/lib/custom/FieldSwitch.d.ts +7 -0
- package/lib/custom/FieldSwitch.js +42 -0
- package/lib/custom/FieldTexarea.d.ts +7 -0
- package/lib/custom/FieldTexarea.js +28 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +14 -14
- package/src/ShowDataComparison.tsx +0 -1
- package/src/custom/CustomFieldUtils.tsx +195 -0
- package/src/custom/FieldAmountLabel.tsx +62 -0
- package/src/custom/FieldCheckbox.tsx +74 -0
- package/src/custom/FieldCombobox.tsx +63 -0
- package/src/custom/FieldDateInput.tsx +75 -0
- package/src/custom/FieldDivider.tsx +18 -0
- package/src/custom/FieldInput.tsx +49 -0
- package/src/custom/FieldJson.tsx +77 -0
- package/src/custom/FieldLabel.tsx +40 -0
- package/src/custom/FieldNumberInput.tsx +60 -0
- package/src/custom/FieldRadio.tsx +73 -0
- package/src/custom/FieldSelect.tsx +70 -0
- package/src/custom/FieldSwitch.tsx +58 -0
- package/src/custom/FieldTexarea.tsx +54 -0
- package/src/index.ts +2 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { IdType } from "@etsoo/shared";
|
|
2
|
+
import { Typography } from "@mui/material";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { ComboBoxMultiple } from "../ComboBoxMultiple";
|
|
5
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Combobox (multiple values) field creator
|
|
9
|
+
* type combobox
|
|
10
|
+
* @returns Component
|
|
11
|
+
*/
|
|
12
|
+
export const FieldCombobox: ICustomFieldReact<IdType[]> = ({
|
|
13
|
+
field,
|
|
14
|
+
mref,
|
|
15
|
+
onChange,
|
|
16
|
+
defaultValue
|
|
17
|
+
}) => {
|
|
18
|
+
// State
|
|
19
|
+
const [ids, setIds] = React.useState<IdType[]>();
|
|
20
|
+
|
|
21
|
+
const getValue = () => ids;
|
|
22
|
+
const setValue = (value: unknown) => {
|
|
23
|
+
if (Array.isArray(value)) setIds(value);
|
|
24
|
+
else if (typeof value === "number" || typeof value === "string")
|
|
25
|
+
setIds([value]);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Ref
|
|
29
|
+
React.useImperativeHandle(mref, () => ({
|
|
30
|
+
getValue,
|
|
31
|
+
setValue
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
React.useEffect(() => {
|
|
35
|
+
if (defaultValue == null) return;
|
|
36
|
+
setValue(defaultValue);
|
|
37
|
+
}, [defaultValue]);
|
|
38
|
+
|
|
39
|
+
// Name
|
|
40
|
+
const name = field.name;
|
|
41
|
+
if (!name) {
|
|
42
|
+
return (
|
|
43
|
+
<Typography>No name for FieldCombobox {JSON.stringify(field)}</Typography>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<ComboBoxMultiple
|
|
49
|
+
label={field.label ?? ""}
|
|
50
|
+
inputHelperText={field.helperText}
|
|
51
|
+
name={name}
|
|
52
|
+
options={field.options}
|
|
53
|
+
fullWidth
|
|
54
|
+
idValues={ids}
|
|
55
|
+
onChange={(_event, value) => {
|
|
56
|
+
const ids = value.map((v) => v.id);
|
|
57
|
+
setIds(ids);
|
|
58
|
+
onChange(name, ids);
|
|
59
|
+
}}
|
|
60
|
+
{...field.mainSlotProps}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
2
|
+
import { DateUtils } from "@etsoo/shared";
|
|
3
|
+
import { Typography } from "@mui/material";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import { InputField } from "../InputField";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Date input field creator
|
|
9
|
+
* type: date
|
|
10
|
+
* @returns Component
|
|
11
|
+
*/
|
|
12
|
+
export const FieldDateInput: ICustomFieldReact<Date> = ({
|
|
13
|
+
field,
|
|
14
|
+
mref,
|
|
15
|
+
onChange,
|
|
16
|
+
defaultValue
|
|
17
|
+
}) => {
|
|
18
|
+
// Ref
|
|
19
|
+
const inputRef = React.useRef<HTMLInputElement>();
|
|
20
|
+
|
|
21
|
+
const getValue = () =>
|
|
22
|
+
inputRef.current == null
|
|
23
|
+
? undefined
|
|
24
|
+
: DateUtils.parse(inputRef.current.value);
|
|
25
|
+
|
|
26
|
+
const setValue = (value: unknown) => {
|
|
27
|
+
if (inputRef.current == null) return;
|
|
28
|
+
|
|
29
|
+
const date =
|
|
30
|
+
value instanceof Date
|
|
31
|
+
? value
|
|
32
|
+
: typeof value === "string"
|
|
33
|
+
? DateUtils.parse(value)
|
|
34
|
+
: undefined;
|
|
35
|
+
|
|
36
|
+
inputRef.current.value =
|
|
37
|
+
DateUtils.formatForInput(
|
|
38
|
+
date,
|
|
39
|
+
inputRef.current.type === "date" ? undefined : false
|
|
40
|
+
) ?? "";
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
React.useImperativeHandle(mref, () => ({
|
|
44
|
+
getValue,
|
|
45
|
+
setValue
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
React.useEffect(() => {
|
|
49
|
+
if (defaultValue == null) return;
|
|
50
|
+
setValue(defaultValue);
|
|
51
|
+
}, [defaultValue]);
|
|
52
|
+
|
|
53
|
+
// Name
|
|
54
|
+
const name = field.name;
|
|
55
|
+
if (!name) {
|
|
56
|
+
return (
|
|
57
|
+
<Typography>
|
|
58
|
+
No name for FieldDateInput {JSON.stringify(field)}
|
|
59
|
+
</Typography>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<InputField
|
|
65
|
+
label={field.label ?? ""}
|
|
66
|
+
helperText={field.helperText}
|
|
67
|
+
inputRef={inputRef}
|
|
68
|
+
type="date"
|
|
69
|
+
name={name}
|
|
70
|
+
fullWidth
|
|
71
|
+
onChange={() => onChange(name, getValue())}
|
|
72
|
+
{...field.mainSlotProps}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
2
|
+
import { Divider } from "@mui/material";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { CustomFieldUtils } from "./CustomFieldUtils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Divider field creator
|
|
8
|
+
* type: divider
|
|
9
|
+
* @returns Component
|
|
10
|
+
*/
|
|
11
|
+
export const FieldDivider: ICustomFieldReact<unknown> = ({ field }) => {
|
|
12
|
+
return (
|
|
13
|
+
<React.Fragment>
|
|
14
|
+
{CustomFieldUtils.createMultilineLabel(field.label)}
|
|
15
|
+
<Divider {...field.mainSlotProps} />
|
|
16
|
+
</React.Fragment>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
2
|
+
import { Typography } from "@mui/material";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { InputField } from "../InputField";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Input field creator
|
|
8
|
+
* type: input
|
|
9
|
+
* @returns Component
|
|
10
|
+
*/
|
|
11
|
+
export const FieldInput: ICustomFieldReact<string> = ({
|
|
12
|
+
field,
|
|
13
|
+
mref,
|
|
14
|
+
onChange,
|
|
15
|
+
defaultValue
|
|
16
|
+
}) => {
|
|
17
|
+
// Ref
|
|
18
|
+
const inputRef = React.useRef<HTMLInputElement>();
|
|
19
|
+
|
|
20
|
+
const getValue = () => inputRef.current?.value;
|
|
21
|
+
|
|
22
|
+
React.useImperativeHandle(mref, () => ({
|
|
23
|
+
getValue,
|
|
24
|
+
setValue(value) {
|
|
25
|
+
if (inputRef.current) inputRef.current.value = `${value ?? ""}`;
|
|
26
|
+
}
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
// Name
|
|
30
|
+
const name = field.name;
|
|
31
|
+
if (!name) {
|
|
32
|
+
return (
|
|
33
|
+
<Typography>No name for FieldInput {JSON.stringify(field)}</Typography>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<InputField
|
|
39
|
+
label={field.label ?? ""}
|
|
40
|
+
helperText={field.helperText}
|
|
41
|
+
inputRef={inputRef}
|
|
42
|
+
name={name}
|
|
43
|
+
fullWidth
|
|
44
|
+
defaultValue={defaultValue}
|
|
45
|
+
onChange={() => onChange(name, getValue())}
|
|
46
|
+
{...field.mainSlotProps}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
2
|
+
import { Typography } from "@mui/material";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { InputField } from "../InputField";
|
|
5
|
+
|
|
6
|
+
function parseJson(value: string | undefined | null) {
|
|
7
|
+
if (value) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(value);
|
|
10
|
+
} catch (error) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Textarea field creator
|
|
19
|
+
* type: json
|
|
20
|
+
* @returns Component
|
|
21
|
+
*/
|
|
22
|
+
export const FieldJson: ICustomFieldReact<object> = ({
|
|
23
|
+
field,
|
|
24
|
+
mref,
|
|
25
|
+
onChange,
|
|
26
|
+
defaultValue
|
|
27
|
+
}) => {
|
|
28
|
+
// Ref
|
|
29
|
+
const inputRef = React.useRef<HTMLInputElement>();
|
|
30
|
+
|
|
31
|
+
const getValue = () => parseJson(inputRef.current?.value);
|
|
32
|
+
|
|
33
|
+
const setValue = (value: unknown) => {
|
|
34
|
+
if (inputRef.current) {
|
|
35
|
+
const obj =
|
|
36
|
+
typeof value === "object"
|
|
37
|
+
? value
|
|
38
|
+
: typeof value === "string"
|
|
39
|
+
? parseJson(value)
|
|
40
|
+
: undefined;
|
|
41
|
+
inputRef.current.value = obj ? JSON.stringify(obj, null, 4) : "";
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
React.useImperativeHandle(mref, () => ({
|
|
46
|
+
getValue,
|
|
47
|
+
setValue
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
if (defaultValue == null) return;
|
|
52
|
+
setValue(defaultValue);
|
|
53
|
+
}, [defaultValue]);
|
|
54
|
+
|
|
55
|
+
// Name
|
|
56
|
+
const name = field.name;
|
|
57
|
+
if (!name) {
|
|
58
|
+
return (
|
|
59
|
+
<Typography>No name for FieldJson {JSON.stringify(field)}</Typography>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<InputField
|
|
65
|
+
label={field.label ?? ""}
|
|
66
|
+
helperText={field.helperText}
|
|
67
|
+
name={name}
|
|
68
|
+
fullWidth
|
|
69
|
+
multiline
|
|
70
|
+
rows={4}
|
|
71
|
+
inputProps={{ maxLength: 1280 }}
|
|
72
|
+
inputRef={inputRef}
|
|
73
|
+
onChange={() => onChange(name, getValue())}
|
|
74
|
+
{...field.mainSlotProps}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CustomFieldUtils } from "./CustomFieldUtils";
|
|
3
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Label field creator
|
|
7
|
+
* type: label
|
|
8
|
+
* @returns Component
|
|
9
|
+
*/
|
|
10
|
+
export const FieldLabel: ICustomFieldReact<string> = ({
|
|
11
|
+
field,
|
|
12
|
+
mref,
|
|
13
|
+
defaultValue
|
|
14
|
+
}) => {
|
|
15
|
+
// State
|
|
16
|
+
const [label, setLabel] = React.useState<string>();
|
|
17
|
+
|
|
18
|
+
// Ref
|
|
19
|
+
const getValue = () => label;
|
|
20
|
+
const setValue = (value: unknown) => setLabel(`${value ?? ""}`);
|
|
21
|
+
React.useImperativeHandle(mref, () => ({
|
|
22
|
+
getValue,
|
|
23
|
+
setValue
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
React.useEffect(() => {
|
|
27
|
+
setLabel(field.label);
|
|
28
|
+
}, [field.label]);
|
|
29
|
+
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
if (defaultValue == null) return;
|
|
32
|
+
setValue(defaultValue);
|
|
33
|
+
}, [defaultValue]);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<React.Fragment>
|
|
37
|
+
{CustomFieldUtils.createMultilineLabel(label, field.mainSlotProps)}
|
|
38
|
+
</React.Fragment>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
2
|
+
import { Typography } from "@mui/material";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { NumberInputField } from "../NumberInputField";
|
|
5
|
+
import { NumberUtils } from "@etsoo/shared";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Number input field creator
|
|
9
|
+
* type: number
|
|
10
|
+
* @returns Component
|
|
11
|
+
*/
|
|
12
|
+
export const FieldNumberInput: ICustomFieldReact<number> = ({
|
|
13
|
+
field,
|
|
14
|
+
mref,
|
|
15
|
+
onChange,
|
|
16
|
+
defaultValue
|
|
17
|
+
}) => {
|
|
18
|
+
// Ref
|
|
19
|
+
const inputRef = React.useRef<HTMLInputElement>();
|
|
20
|
+
|
|
21
|
+
const getValue = () => {
|
|
22
|
+
const value = inputRef.current?.valueAsNumber;
|
|
23
|
+
return NumberUtils.parse(value);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const setValue = (value: unknown) => {
|
|
27
|
+
if (inputRef.current) inputRef.current.value = `${value ?? ""}`;
|
|
28
|
+
};
|
|
29
|
+
React.useImperativeHandle(mref, () => ({
|
|
30
|
+
getValue,
|
|
31
|
+
setValue
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
React.useEffect(() => {
|
|
35
|
+
if (defaultValue == null) return;
|
|
36
|
+
setValue(defaultValue);
|
|
37
|
+
}, [defaultValue]);
|
|
38
|
+
|
|
39
|
+
// Name
|
|
40
|
+
const name = field.name;
|
|
41
|
+
if (!name) {
|
|
42
|
+
return (
|
|
43
|
+
<Typography>
|
|
44
|
+
No name for FieldNumberInput {JSON.stringify(field)}
|
|
45
|
+
</Typography>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<NumberInputField
|
|
51
|
+
label={field.label ?? ""}
|
|
52
|
+
helperText={field.helperText}
|
|
53
|
+
inputRef={inputRef}
|
|
54
|
+
name={name}
|
|
55
|
+
fullWidth
|
|
56
|
+
onChange={() => onChange(name, getValue())}
|
|
57
|
+
{...field.mainSlotProps}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
2
|
+
import { IdType } from "@etsoo/shared";
|
|
3
|
+
import { Typography } from "@mui/material";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import { OptionGroup } from "../OptionGroup";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Radio (single value) field creator
|
|
9
|
+
* type: radio
|
|
10
|
+
* @returns Component
|
|
11
|
+
*/
|
|
12
|
+
export const FieldRadio: ICustomFieldReact<IdType> = ({
|
|
13
|
+
field,
|
|
14
|
+
mref,
|
|
15
|
+
onChange,
|
|
16
|
+
defaultValue
|
|
17
|
+
}) => {
|
|
18
|
+
// State
|
|
19
|
+
const [value, setLocalValue] = React.useState<IdType>();
|
|
20
|
+
|
|
21
|
+
// Ref
|
|
22
|
+
const getValue = () => value;
|
|
23
|
+
const setValue = (value: unknown) => {
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
setLocalValue(value[0]);
|
|
26
|
+
} else if (typeof value === "string" || typeof value === "number") {
|
|
27
|
+
setLocalValue(value);
|
|
28
|
+
} else {
|
|
29
|
+
setLocalValue(undefined);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
React.useImperativeHandle(mref, () => ({
|
|
33
|
+
getValue,
|
|
34
|
+
setValue
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
React.useEffect(() => {
|
|
38
|
+
if (defaultValue == null) return;
|
|
39
|
+
setValue(defaultValue);
|
|
40
|
+
}, [defaultValue]);
|
|
41
|
+
|
|
42
|
+
// Name
|
|
43
|
+
const name = field.name;
|
|
44
|
+
if (!name) {
|
|
45
|
+
return (
|
|
46
|
+
<Typography>No name for FieldRadio {JSON.stringify(field)}</Typography>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<OptionGroup
|
|
52
|
+
name={name}
|
|
53
|
+
options={field.options ?? []}
|
|
54
|
+
multiple={false}
|
|
55
|
+
row
|
|
56
|
+
helperText={field.helperText}
|
|
57
|
+
label={field.label}
|
|
58
|
+
variant="outlined"
|
|
59
|
+
fullWidth
|
|
60
|
+
defaultValue={value}
|
|
61
|
+
onValueChange={(value) => {
|
|
62
|
+
const newValue = Array.isArray(value)
|
|
63
|
+
? value[0]
|
|
64
|
+
: value == null
|
|
65
|
+
? undefined
|
|
66
|
+
: value;
|
|
67
|
+
setLocalValue(newValue);
|
|
68
|
+
onChange(name, newValue);
|
|
69
|
+
}}
|
|
70
|
+
{...field.mainSlotProps}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { IdType } from "@etsoo/shared";
|
|
2
|
+
import { Typography } from "@mui/material";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
5
|
+
import { SelectEx } from "../SelectEx";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Select (single value) field creator
|
|
9
|
+
* type select
|
|
10
|
+
* @returns Component
|
|
11
|
+
*/
|
|
12
|
+
export const FieldSelect: ICustomFieldReact<IdType> = ({
|
|
13
|
+
field,
|
|
14
|
+
mref,
|
|
15
|
+
onChange,
|
|
16
|
+
defaultValue
|
|
17
|
+
}) => {
|
|
18
|
+
// State
|
|
19
|
+
const [value, setLocalValue] = React.useState<IdType>();
|
|
20
|
+
|
|
21
|
+
const getValue = () => value;
|
|
22
|
+
const setValue = (value: unknown) => {
|
|
23
|
+
if (Array.isArray(value)) {
|
|
24
|
+
setLocalValue(value[0]);
|
|
25
|
+
} else if (typeof value === "string" || typeof value === "number") {
|
|
26
|
+
setLocalValue(value);
|
|
27
|
+
} else {
|
|
28
|
+
setLocalValue(undefined);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Ref
|
|
33
|
+
React.useImperativeHandle(mref, () => ({
|
|
34
|
+
getValue,
|
|
35
|
+
setValue
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
React.useEffect(() => {
|
|
39
|
+
if (defaultValue == null) return;
|
|
40
|
+
setValue(defaultValue);
|
|
41
|
+
}, [defaultValue]);
|
|
42
|
+
|
|
43
|
+
// Name
|
|
44
|
+
const name = field.name;
|
|
45
|
+
if (!name) {
|
|
46
|
+
return (
|
|
47
|
+
<Typography>No name for FieldSelect {JSON.stringify(field)}</Typography>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<SelectEx
|
|
53
|
+
label={field.label ?? ""}
|
|
54
|
+
helperText={field.helperText}
|
|
55
|
+
name={name}
|
|
56
|
+
options={field.options}
|
|
57
|
+
fullWidth
|
|
58
|
+
onChange={(event) => {
|
|
59
|
+
const value = event.target.value;
|
|
60
|
+
const newValue =
|
|
61
|
+
typeof value === "string" || typeof value === "number"
|
|
62
|
+
? value
|
|
63
|
+
: undefined;
|
|
64
|
+
setLocalValue(newValue);
|
|
65
|
+
onChange(name, newValue);
|
|
66
|
+
}}
|
|
67
|
+
{...field.mainSlotProps}
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { SwitchAnt } from "../SwitchAnt";
|
|
4
|
+
import { Typography } from "@mui/material";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Input field creator
|
|
8
|
+
* type: switch
|
|
9
|
+
* @returns Component
|
|
10
|
+
*/
|
|
11
|
+
export const FieldSwitch: ICustomFieldReact<boolean> = ({
|
|
12
|
+
field,
|
|
13
|
+
mref,
|
|
14
|
+
onChange,
|
|
15
|
+
defaultValue
|
|
16
|
+
}) => {
|
|
17
|
+
// State
|
|
18
|
+
const [value, setLocalValue] = React.useState<boolean>();
|
|
19
|
+
|
|
20
|
+
const getValue = () => value;
|
|
21
|
+
const setValue = (value: unknown) => {
|
|
22
|
+
if (typeof value === "boolean") setLocalValue(value);
|
|
23
|
+
else if (value === "true" || value === "1" || value === 1)
|
|
24
|
+
setLocalValue(true);
|
|
25
|
+
else if (value === "false" || value === "0" || value === 0)
|
|
26
|
+
setLocalValue(false);
|
|
27
|
+
else setLocalValue(undefined);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
React.useImperativeHandle(mref, () => ({
|
|
31
|
+
getValue,
|
|
32
|
+
setValue
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
// Name
|
|
36
|
+
const name = field.name;
|
|
37
|
+
if (!name) {
|
|
38
|
+
return (
|
|
39
|
+
<Typography>No name for FieldSwitch {JSON.stringify(field)}</Typography>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
React.useEffect(() => {
|
|
44
|
+
if (defaultValue == null) return;
|
|
45
|
+
setValue(defaultValue);
|
|
46
|
+
}, [defaultValue]);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<SwitchAnt
|
|
50
|
+
name={name}
|
|
51
|
+
onChange={(_event, value) => {
|
|
52
|
+
setLocalValue(value);
|
|
53
|
+
onChange(name, value);
|
|
54
|
+
}}
|
|
55
|
+
{...field.mainSlotProps}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ICustomFieldReact } from "@etsoo/react";
|
|
2
|
+
import { Typography } from "@mui/material";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { InputField } from "../InputField";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Textarea field creator
|
|
8
|
+
* type: textarea
|
|
9
|
+
* @returns Component
|
|
10
|
+
*/
|
|
11
|
+
export const FieldTexarea: ICustomFieldReact<string> = ({
|
|
12
|
+
field,
|
|
13
|
+
mref,
|
|
14
|
+
onChange,
|
|
15
|
+
defaultValue
|
|
16
|
+
}) => {
|
|
17
|
+
// Ref
|
|
18
|
+
const inputRef = React.useRef<HTMLInputElement>();
|
|
19
|
+
|
|
20
|
+
const getValue = () => inputRef.current?.value;
|
|
21
|
+
|
|
22
|
+
const setValue = (value: unknown) => {
|
|
23
|
+
if (inputRef.current) inputRef.current.value = `${value ?? ""}`;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
React.useImperativeHandle(mref, () => ({
|
|
27
|
+
getValue,
|
|
28
|
+
setValue
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
// Name
|
|
32
|
+
const name = field.name;
|
|
33
|
+
if (!name) {
|
|
34
|
+
return (
|
|
35
|
+
<Typography>No name for FieldTextarea {JSON.stringify(field)}</Typography>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<InputField
|
|
41
|
+
label={field.label ?? ""}
|
|
42
|
+
helperText={field.helperText}
|
|
43
|
+
name={name}
|
|
44
|
+
fullWidth
|
|
45
|
+
multiline
|
|
46
|
+
rows={4}
|
|
47
|
+
inputProps={{ maxLength: 1280 }}
|
|
48
|
+
inputRef={inputRef}
|
|
49
|
+
defaultValue={defaultValue}
|
|
50
|
+
onChange={() => onChange(name, getValue())}
|
|
51
|
+
{...field.mainSlotProps}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,8 @@ export * from "./app/Labels";
|
|
|
9
9
|
export * from "./app/ReactApp";
|
|
10
10
|
export * from "./app/ServiceApp";
|
|
11
11
|
|
|
12
|
+
export * from "./custom/CustomFieldUtils";
|
|
13
|
+
|
|
12
14
|
export * from "./messages/MessageUtils";
|
|
13
15
|
export * from "./messages/OperationMessageContainer";
|
|
14
16
|
export * from "./messages/OperationMessageDto";
|