@etsoo/materialui 1.6.2 → 1.6.4
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/lib/cjs/IntInputField.js +23 -5
- package/lib/cjs/TagList.js +1 -0
- package/lib/cjs/TagListPro.d.ts +4 -0
- package/lib/cjs/TagListPro.js +14 -3
- package/lib/mjs/IntInputField.js +23 -5
- package/lib/mjs/TagList.js +1 -0
- package/lib/mjs/TagListPro.d.ts +4 -0
- package/lib/mjs/TagListPro.js +14 -3
- package/package.json +10 -10
- package/src/IntInputField.tsx +27 -4
- package/src/TagList.tsx +1 -0
- package/src/TagListPro.tsx +19 -2
package/lib/cjs/IntInputField.js
CHANGED
|
@@ -13,14 +13,25 @@ const InputField_1 = require("./InputField");
|
|
|
13
13
|
const Box_1 = __importDefault(require("@mui/material/Box"));
|
|
14
14
|
const InputAdornment_1 = __importDefault(require("@mui/material/InputAdornment"));
|
|
15
15
|
const IconButton_1 = __importDefault(require("@mui/material/IconButton"));
|
|
16
|
+
const react_2 = require("@etsoo/react");
|
|
16
17
|
/**
|
|
17
18
|
* Integer input field (controlled)
|
|
18
19
|
*/
|
|
19
20
|
function IntInputField(props) {
|
|
20
21
|
// Destruct
|
|
21
|
-
const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = [600], onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props;
|
|
22
|
+
const { min = 0, step = 1, max = 9999999, inputRef, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = [600], onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props;
|
|
23
|
+
const isControlled = value !== undefined;
|
|
22
24
|
// State
|
|
23
|
-
const [localValue,
|
|
25
|
+
const [localValue, setInnerLocalValue] = react_1.default.useState();
|
|
26
|
+
const localRef = react_1.default.useRef(null);
|
|
27
|
+
function setLocalValue(value) {
|
|
28
|
+
if (isControlled) {
|
|
29
|
+
setInnerLocalValue(value);
|
|
30
|
+
}
|
|
31
|
+
else if (localRef.current) {
|
|
32
|
+
localRef.current.value = value?.toString() ?? "";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
24
35
|
const setValue = (value, source, init = false) => {
|
|
25
36
|
if (onValueChange) {
|
|
26
37
|
const newValue = onValueChange(value, source, init);
|
|
@@ -40,10 +51,17 @@ function IntInputField(props) {
|
|
|
40
51
|
}
|
|
41
52
|
};
|
|
42
53
|
react_1.default.useEffect(() => {
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
if (isControlled)
|
|
55
|
+
setValue(value, undefined, true);
|
|
56
|
+
}, [value, isControlled]);
|
|
45
57
|
// Layout
|
|
46
|
-
const layout = ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { type: "number",
|
|
58
|
+
const layout = ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { type: "number", inputRef: (0, react_2.useCombinedRefs)(inputRef, localRef), value: isControlled
|
|
59
|
+
? localValue == null
|
|
60
|
+
? required
|
|
61
|
+
? min
|
|
62
|
+
: ""
|
|
63
|
+
: localValue
|
|
64
|
+
: undefined, slotProps: {
|
|
47
65
|
input: {
|
|
48
66
|
startAdornment: symbol ? ((0, jsx_runtime_1.jsx)(react_1.default.Fragment, { children: (0, jsx_runtime_1.jsx)(InputAdornment_1.default, { position: "start", children: symbol }) })) : undefined,
|
|
49
67
|
endAdornment: endSymbol ? ((0, jsx_runtime_1.jsx)(InputAdornment_1.default, { position: "end", children: endSymbol })) : undefined
|
package/lib/cjs/TagList.js
CHANGED
|
@@ -53,6 +53,7 @@ function TagList(props) {
|
|
|
53
53
|
loadDataLocal();
|
|
54
54
|
}
|
|
55
55
|
}, onClose: () => {
|
|
56
|
+
setOptions([]);
|
|
56
57
|
setOpen(false);
|
|
57
58
|
}, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, clearOnBlur: true, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, onChangeDelay: async (event) => {
|
|
58
59
|
// Stop bubble
|
package/lib/cjs/TagListPro.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ export type TagListProProps<D extends ListType2 = ListType2> = Omit<Autocomplete
|
|
|
10
10
|
* Load data callback
|
|
11
11
|
*/
|
|
12
12
|
loadData: (keyword: string | undefined, items: number) => PromiseLike<D[] | null | undefined>;
|
|
13
|
+
/**
|
|
14
|
+
* Load value from ids
|
|
15
|
+
*/
|
|
16
|
+
loadIdValue?: () => PromiseLike<D[] | null | undefined>;
|
|
13
17
|
/**
|
|
14
18
|
* Input props
|
|
15
19
|
*/
|
package/lib/cjs/TagListPro.js
CHANGED
|
@@ -25,12 +25,13 @@ function TagListPro(props) {
|
|
|
25
25
|
const { getOptionKey = (option) => typeof option === "string" ? option : option.id, renderOption = ({ key, ...props }, option, { selected }) => ((0, jsx_runtime_1.jsx)("li", { ...props, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Checkbox_1.default, { icon: (0, jsx_runtime_1.jsx)(CheckBoxOutlineBlank_1.default, { fontSize: "small" }), checkedIcon: (0, jsx_runtime_1.jsx)(CheckBox_1.default, { fontSize: "small" }), style: { marginRight: 8 }, checked: selected }), getLabel(option)] }) }, key)), renderValue = (value, getTagProps) => value.map((option, index) => {
|
|
26
26
|
const { key, ...rest } = getTagProps({ index });
|
|
27
27
|
return ((0, jsx_runtime_1.jsx)(Chip_1.default, { variant: "outlined", label: getLabel(option), ...rest }, key));
|
|
28
|
-
}), noOptionsText = noOptions, loadingText = loadingLabel, openText = openDefault, loadData, maxItems = 16, disableCloseOnSelect = true, openOnFocus = true, label, inputProps, onChange, value, ...rest } = props;
|
|
28
|
+
}), noOptionsText = noOptions, loadingText = loadingLabel, openText = openDefault, loadData, loadIdValue, maxItems = 16, disableCloseOnSelect = true, openOnFocus = true, label, inputProps, onChange, value, ...rest } = props;
|
|
29
29
|
const [open, setOpen] = react_1.default.useState(false);
|
|
30
30
|
const [options, setOptions] = react_1.default.useState([]);
|
|
31
31
|
const [loading, setLoading] = react_1.default.useState(false);
|
|
32
|
+
const [valueState, setValueState] = react_1.default.useState(value ?? []);
|
|
32
33
|
const currentValue = react_1.default.useRef([]);
|
|
33
|
-
currentValue.current =
|
|
34
|
+
currentValue.current = valueState;
|
|
34
35
|
const loadDataLocal = async (keyword) => {
|
|
35
36
|
setLoading(true);
|
|
36
37
|
const result = (await loadData(keyword, maxItems)) ?? [];
|
|
@@ -49,12 +50,22 @@ function TagListPro(props) {
|
|
|
49
50
|
setOptions(result);
|
|
50
51
|
setLoading(false);
|
|
51
52
|
};
|
|
53
|
+
react_1.default.useEffect(() => {
|
|
54
|
+
if (loadIdValue) {
|
|
55
|
+
loadIdValue().then((result) => {
|
|
56
|
+
if (result == null)
|
|
57
|
+
return;
|
|
58
|
+
setValueState(result);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}, [loadIdValue]);
|
|
52
62
|
return ((0, jsx_runtime_1.jsx)(Autocomplete_1.default, { multiple: true, filterOptions: (options, _state) => options, open: open, onOpen: () => {
|
|
53
63
|
setOpen(true);
|
|
54
64
|
if (options.length === 0) {
|
|
55
65
|
loadDataLocal();
|
|
56
66
|
}
|
|
57
67
|
}, onClose: () => {
|
|
68
|
+
setOptions([]);
|
|
58
69
|
setOpen(false);
|
|
59
70
|
}, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, onChangeDelay: async (event) => {
|
|
60
71
|
// Stop bubble
|
|
@@ -65,7 +76,7 @@ function TagListPro(props) {
|
|
|
65
76
|
return (typeof item.id === "number" &&
|
|
66
77
|
item.id < 0 &&
|
|
67
78
|
getLabel(item) === moreLabel);
|
|
68
|
-
}, getOptionLabel: (item) => getLabel(item), getOptionKey: getOptionKey, isOptionEqualToValue: (option, value) => option.id === value.id, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, value:
|
|
79
|
+
}, getOptionLabel: (item) => getLabel(item), getOptionKey: getOptionKey, isOptionEqualToValue: (option, value) => option.id === value.id, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, value: valueState, onChange: (event, value, reason, details) => {
|
|
69
80
|
currentValue.current = value;
|
|
70
81
|
if (onChange)
|
|
71
82
|
onChange(event, value, reason, details);
|
package/lib/mjs/IntInputField.js
CHANGED
|
@@ -7,14 +7,25 @@ import { InputField } from "./InputField";
|
|
|
7
7
|
import Box from "@mui/material/Box";
|
|
8
8
|
import InputAdornment from "@mui/material/InputAdornment";
|
|
9
9
|
import IconButton from "@mui/material/IconButton";
|
|
10
|
+
import { useCombinedRefs } from "@etsoo/react";
|
|
10
11
|
/**
|
|
11
12
|
* Integer input field (controlled)
|
|
12
13
|
*/
|
|
13
14
|
export function IntInputField(props) {
|
|
14
15
|
// Destruct
|
|
15
|
-
const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = [600], onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props;
|
|
16
|
+
const { min = 0, step = 1, max = 9999999, inputRef, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = [600], onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props;
|
|
17
|
+
const isControlled = value !== undefined;
|
|
16
18
|
// State
|
|
17
|
-
const [localValue,
|
|
19
|
+
const [localValue, setInnerLocalValue] = React.useState();
|
|
20
|
+
const localRef = React.useRef(null);
|
|
21
|
+
function setLocalValue(value) {
|
|
22
|
+
if (isControlled) {
|
|
23
|
+
setInnerLocalValue(value);
|
|
24
|
+
}
|
|
25
|
+
else if (localRef.current) {
|
|
26
|
+
localRef.current.value = value?.toString() ?? "";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
18
29
|
const setValue = (value, source, init = false) => {
|
|
19
30
|
if (onValueChange) {
|
|
20
31
|
const newValue = onValueChange(value, source, init);
|
|
@@ -34,10 +45,17 @@ export function IntInputField(props) {
|
|
|
34
45
|
}
|
|
35
46
|
};
|
|
36
47
|
React.useEffect(() => {
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
if (isControlled)
|
|
49
|
+
setValue(value, undefined, true);
|
|
50
|
+
}, [value, isControlled]);
|
|
39
51
|
// Layout
|
|
40
|
-
const layout = (_jsx(InputField, { type: "number",
|
|
52
|
+
const layout = (_jsx(InputField, { type: "number", inputRef: useCombinedRefs(inputRef, localRef), value: isControlled
|
|
53
|
+
? localValue == null
|
|
54
|
+
? required
|
|
55
|
+
? min
|
|
56
|
+
: ""
|
|
57
|
+
: localValue
|
|
58
|
+
: undefined, slotProps: {
|
|
41
59
|
input: {
|
|
42
60
|
startAdornment: symbol ? (_jsx(React.Fragment, { children: _jsx(InputAdornment, { position: "start", children: symbol }) })) : undefined,
|
|
43
61
|
endAdornment: endSymbol ? (_jsx(InputAdornment, { position: "end", children: endSymbol })) : undefined
|
package/lib/mjs/TagList.js
CHANGED
|
@@ -47,6 +47,7 @@ export function TagList(props) {
|
|
|
47
47
|
loadDataLocal();
|
|
48
48
|
}
|
|
49
49
|
}, onClose: () => {
|
|
50
|
+
setOptions([]);
|
|
50
51
|
setOpen(false);
|
|
51
52
|
}, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, clearOnBlur: true, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => (_jsx(InputField, { label: label, onChangeDelay: async (event) => {
|
|
52
53
|
// Stop bubble
|
package/lib/mjs/TagListPro.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ export type TagListProProps<D extends ListType2 = ListType2> = Omit<Autocomplete
|
|
|
10
10
|
* Load data callback
|
|
11
11
|
*/
|
|
12
12
|
loadData: (keyword: string | undefined, items: number) => PromiseLike<D[] | null | undefined>;
|
|
13
|
+
/**
|
|
14
|
+
* Load value from ids
|
|
15
|
+
*/
|
|
16
|
+
loadIdValue?: () => PromiseLike<D[] | null | undefined>;
|
|
13
17
|
/**
|
|
14
18
|
* Input props
|
|
15
19
|
*/
|
package/lib/mjs/TagListPro.js
CHANGED
|
@@ -19,12 +19,13 @@ export function TagListPro(props) {
|
|
|
19
19
|
const { getOptionKey = (option) => typeof option === "string" ? option : option.id, renderOption = ({ key, ...props }, option, { selected }) => (_jsx("li", { ...props, children: _jsxs(_Fragment, { children: [_jsx(Checkbox, { icon: _jsx(CheckBoxOutlineBlankIcon, { fontSize: "small" }), checkedIcon: _jsx(CheckBoxIcon, { fontSize: "small" }), style: { marginRight: 8 }, checked: selected }), getLabel(option)] }) }, key)), renderValue = (value, getTagProps) => value.map((option, index) => {
|
|
20
20
|
const { key, ...rest } = getTagProps({ index });
|
|
21
21
|
return (_jsx(Chip, { variant: "outlined", label: getLabel(option), ...rest }, key));
|
|
22
|
-
}), noOptionsText = noOptions, loadingText = loadingLabel, openText = openDefault, loadData, maxItems = 16, disableCloseOnSelect = true, openOnFocus = true, label, inputProps, onChange, value, ...rest } = props;
|
|
22
|
+
}), noOptionsText = noOptions, loadingText = loadingLabel, openText = openDefault, loadData, loadIdValue, maxItems = 16, disableCloseOnSelect = true, openOnFocus = true, label, inputProps, onChange, value, ...rest } = props;
|
|
23
23
|
const [open, setOpen] = React.useState(false);
|
|
24
24
|
const [options, setOptions] = React.useState([]);
|
|
25
25
|
const [loading, setLoading] = React.useState(false);
|
|
26
|
+
const [valueState, setValueState] = React.useState(value ?? []);
|
|
26
27
|
const currentValue = React.useRef([]);
|
|
27
|
-
currentValue.current =
|
|
28
|
+
currentValue.current = valueState;
|
|
28
29
|
const loadDataLocal = async (keyword) => {
|
|
29
30
|
setLoading(true);
|
|
30
31
|
const result = (await loadData(keyword, maxItems)) ?? [];
|
|
@@ -43,12 +44,22 @@ export function TagListPro(props) {
|
|
|
43
44
|
setOptions(result);
|
|
44
45
|
setLoading(false);
|
|
45
46
|
};
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
if (loadIdValue) {
|
|
49
|
+
loadIdValue().then((result) => {
|
|
50
|
+
if (result == null)
|
|
51
|
+
return;
|
|
52
|
+
setValueState(result);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}, [loadIdValue]);
|
|
46
56
|
return (_jsx(Autocomplete, { multiple: true, filterOptions: (options, _state) => options, open: open, onOpen: () => {
|
|
47
57
|
setOpen(true);
|
|
48
58
|
if (options.length === 0) {
|
|
49
59
|
loadDataLocal();
|
|
50
60
|
}
|
|
51
61
|
}, onClose: () => {
|
|
62
|
+
setOptions([]);
|
|
52
63
|
setOpen(false);
|
|
53
64
|
}, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => (_jsx(InputField, { label: label, onChangeDelay: async (event) => {
|
|
54
65
|
// Stop bubble
|
|
@@ -59,7 +70,7 @@ export function TagListPro(props) {
|
|
|
59
70
|
return (typeof item.id === "number" &&
|
|
60
71
|
item.id < 0 &&
|
|
61
72
|
getLabel(item) === moreLabel);
|
|
62
|
-
}, getOptionLabel: (item) => getLabel(item), getOptionKey: getOptionKey, isOptionEqualToValue: (option, value) => option.id === value.id, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, value:
|
|
73
|
+
}, getOptionLabel: (item) => getLabel(item), getOptionKey: getOptionKey, isOptionEqualToValue: (option, value) => option.id === value.id, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, value: valueState, onChange: (event, value, reason, details) => {
|
|
63
74
|
currentValue.current = value;
|
|
64
75
|
if (onChange)
|
|
65
76
|
onChange(event, value, reason, details);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.4",
|
|
4
4
|
"description": "TypeScript Material-UI Implementation",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/mjs/index.js",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"@dnd-kit/sortable": "^10.0.0",
|
|
41
41
|
"@emotion/react": "^11.14.0",
|
|
42
42
|
"@emotion/styled": "^11.14.1",
|
|
43
|
-
"@etsoo/appscript": "^1.6.
|
|
43
|
+
"@etsoo/appscript": "^1.6.53",
|
|
44
44
|
"@etsoo/notificationbase": "^1.1.66",
|
|
45
|
-
"@etsoo/react": "^1.8.
|
|
45
|
+
"@etsoo/react": "^1.8.71",
|
|
46
46
|
"@etsoo/shared": "^1.2.80",
|
|
47
47
|
"@mui/icons-material": "^7.3.7",
|
|
48
48
|
"@mui/material": "^7.3.7",
|
|
49
|
-
"@mui/x-data-grid": "^8.
|
|
49
|
+
"@mui/x-data-grid": "^8.25.0",
|
|
50
50
|
"chart.js": "^4.5.1",
|
|
51
51
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
52
52
|
"dompurify": "^3.3.1",
|
|
@@ -65,23 +65,23 @@
|
|
|
65
65
|
"react-dom": "$react-dom"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@babel/cli": "^7.28.
|
|
69
|
-
"@babel/core": "^7.28.
|
|
68
|
+
"@babel/cli": "^7.28.6",
|
|
69
|
+
"@babel/core": "^7.28.6",
|
|
70
70
|
"@babel/plugin-transform-runtime": "^7.28.5",
|
|
71
|
-
"@babel/preset-env": "^7.28.
|
|
71
|
+
"@babel/preset-env": "^7.28.6",
|
|
72
72
|
"@babel/preset-react": "^7.28.5",
|
|
73
73
|
"@babel/preset-typescript": "^7.28.5",
|
|
74
|
-
"@babel/runtime-corejs3": "^7.28.
|
|
74
|
+
"@babel/runtime-corejs3": "^7.28.6",
|
|
75
75
|
"@testing-library/react": "^16.3.1",
|
|
76
76
|
"@types/pica": "^9.0.5",
|
|
77
77
|
"@types/pulltorefreshjs": "^0.1.7",
|
|
78
|
-
"@types/react": "^19.2.
|
|
78
|
+
"@types/react": "^19.2.8",
|
|
79
79
|
"@types/react-avatar-editor": "^13.0.4",
|
|
80
80
|
"@types/react-dom": "^19.2.3",
|
|
81
81
|
"@types/react-input-mask": "^3.0.6",
|
|
82
82
|
"@vitejs/plugin-react": "^5.1.2",
|
|
83
83
|
"jsdom": "^27.4.0",
|
|
84
84
|
"typescript": "^5.9.3",
|
|
85
|
-
"vitest": "^4.0.
|
|
85
|
+
"vitest": "^4.0.17"
|
|
86
86
|
}
|
|
87
87
|
}
|
package/src/IntInputField.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import { InputField, InputFieldProps } from "./InputField";
|
|
|
6
6
|
import Box, { BoxProps } from "@mui/material/Box";
|
|
7
7
|
import InputAdornment from "@mui/material/InputAdornment";
|
|
8
8
|
import IconButton from "@mui/material/IconButton";
|
|
9
|
+
import { useCombinedRefs } from "@etsoo/react";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Integer input field props
|
|
@@ -81,6 +82,7 @@ export function IntInputField(props: IntInputFieldProps) {
|
|
|
81
82
|
min = 0,
|
|
82
83
|
step = 1,
|
|
83
84
|
max = 9999999,
|
|
85
|
+
inputRef,
|
|
84
86
|
inputStyle = { textAlign: "right" },
|
|
85
87
|
boxProps,
|
|
86
88
|
buttons,
|
|
@@ -96,8 +98,20 @@ export function IntInputField(props: IntInputFieldProps) {
|
|
|
96
98
|
...rest
|
|
97
99
|
} = props;
|
|
98
100
|
|
|
101
|
+
const isControlled = value !== undefined;
|
|
102
|
+
|
|
99
103
|
// State
|
|
100
|
-
const [localValue,
|
|
104
|
+
const [localValue, setInnerLocalValue] = React.useState<number | string>();
|
|
105
|
+
|
|
106
|
+
const localRef = React.useRef<HTMLInputElement>(null);
|
|
107
|
+
|
|
108
|
+
function setLocalValue(value: number | string | undefined) {
|
|
109
|
+
if (isControlled) {
|
|
110
|
+
setInnerLocalValue(value);
|
|
111
|
+
} else if (localRef.current) {
|
|
112
|
+
localRef.current.value = value?.toString() ?? "";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
101
115
|
|
|
102
116
|
const setValue = (
|
|
103
117
|
value: number | undefined,
|
|
@@ -121,14 +135,23 @@ export function IntInputField(props: IntInputFieldProps) {
|
|
|
121
135
|
};
|
|
122
136
|
|
|
123
137
|
React.useEffect(() => {
|
|
124
|
-
setValue(value, undefined, true);
|
|
125
|
-
}, [value]);
|
|
138
|
+
if (isControlled) setValue(value, undefined, true);
|
|
139
|
+
}, [value, isControlled]);
|
|
126
140
|
|
|
127
141
|
// Layout
|
|
128
142
|
const layout = (
|
|
129
143
|
<InputField
|
|
130
144
|
type="number"
|
|
131
|
-
|
|
145
|
+
inputRef={useCombinedRefs(inputRef, localRef)}
|
|
146
|
+
value={
|
|
147
|
+
isControlled
|
|
148
|
+
? localValue == null
|
|
149
|
+
? required
|
|
150
|
+
? min
|
|
151
|
+
: ""
|
|
152
|
+
: localValue
|
|
153
|
+
: undefined
|
|
154
|
+
}
|
|
132
155
|
slotProps={{
|
|
133
156
|
input: {
|
|
134
157
|
startAdornment: symbol ? (
|
package/src/TagList.tsx
CHANGED
package/src/TagListPro.tsx
CHANGED
|
@@ -25,6 +25,11 @@ export type TagListProProps<D extends ListType2 = ListType2> = Omit<
|
|
|
25
25
|
items: number
|
|
26
26
|
) => PromiseLike<D[] | null | undefined>;
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Load value from ids
|
|
30
|
+
*/
|
|
31
|
+
loadIdValue?: () => PromiseLike<D[] | null | undefined>;
|
|
32
|
+
|
|
28
33
|
/**
|
|
29
34
|
* Input props
|
|
30
35
|
*/
|
|
@@ -87,6 +92,7 @@ export function TagListPro<D extends ListType2 = ListType2>(
|
|
|
87
92
|
loadingText = loadingLabel,
|
|
88
93
|
openText = openDefault,
|
|
89
94
|
loadData,
|
|
95
|
+
loadIdValue,
|
|
90
96
|
maxItems = 16,
|
|
91
97
|
disableCloseOnSelect = true,
|
|
92
98
|
openOnFocus = true,
|
|
@@ -100,9 +106,10 @@ export function TagListPro<D extends ListType2 = ListType2>(
|
|
|
100
106
|
const [open, setOpen] = React.useState(false);
|
|
101
107
|
const [options, setOptions] = React.useState<readonly D[]>([]);
|
|
102
108
|
const [loading, setLoading] = React.useState(false);
|
|
109
|
+
const [valueState, setValueState] = React.useState<D[]>(value ?? []);
|
|
103
110
|
|
|
104
111
|
const currentValue = React.useRef<readonly D[]>([]);
|
|
105
|
-
currentValue.current =
|
|
112
|
+
currentValue.current = valueState;
|
|
106
113
|
|
|
107
114
|
const loadDataLocal = async (keyword?: string) => {
|
|
108
115
|
setLoading(true);
|
|
@@ -124,6 +131,15 @@ export function TagListPro<D extends ListType2 = ListType2>(
|
|
|
124
131
|
setLoading(false);
|
|
125
132
|
};
|
|
126
133
|
|
|
134
|
+
React.useEffect(() => {
|
|
135
|
+
if (loadIdValue) {
|
|
136
|
+
loadIdValue().then((result) => {
|
|
137
|
+
if (result == null) return;
|
|
138
|
+
setValueState(result);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}, [loadIdValue]);
|
|
142
|
+
|
|
127
143
|
return (
|
|
128
144
|
<Autocomplete<D, true, false, false>
|
|
129
145
|
multiple
|
|
@@ -136,6 +152,7 @@ export function TagListPro<D extends ListType2 = ListType2>(
|
|
|
136
152
|
}
|
|
137
153
|
}}
|
|
138
154
|
onClose={() => {
|
|
155
|
+
setOptions([]);
|
|
139
156
|
setOpen(false);
|
|
140
157
|
}}
|
|
141
158
|
options={options}
|
|
@@ -171,7 +188,7 @@ export function TagListPro<D extends ListType2 = ListType2>(
|
|
|
171
188
|
noOptionsText={noOptionsText}
|
|
172
189
|
loadingText={loadingText}
|
|
173
190
|
openText={openText}
|
|
174
|
-
value={
|
|
191
|
+
value={valueState}
|
|
175
192
|
onChange={(event, value, reason, details) => {
|
|
176
193
|
currentValue.current = value;
|
|
177
194
|
if (onChange) onChange(event, value, reason, details);
|