@etsoo/materialui 1.1.45 → 1.1.47
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/AddresSelector.d.ts +12 -0
- package/lib/AddresSelector.js +32 -15
- package/lib/ComboBox.js +3 -3
- package/lib/HiSelector.d.ts +5 -1
- package/lib/HiSelector.js +5 -5
- package/lib/HiSelectorTL.d.ts +5 -1
- package/lib/HiSelectorTL.js +5 -5
- package/lib/Tiplist.js +3 -3
- package/package.json +12 -12
- package/src/AddresSelector.tsx +73 -23
- package/src/ComboBox.tsx +3 -1
- package/src/HiSelector.tsx +16 -5
- package/src/HiSelectorTL.tsx +12 -5
- package/src/Tiplist.tsx +8 -2
package/lib/AddresSelector.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AddressApi, AddressCity, AddressDistrict, AddressRegionDb, AddressState } from "@etsoo/appscript";
|
|
2
|
+
import { RegularBreakpoints } from "@mui/material";
|
|
2
3
|
import React from "react";
|
|
3
4
|
/**
|
|
4
5
|
* Address field
|
|
@@ -10,6 +11,7 @@ export declare enum AddressField {
|
|
|
10
11
|
District = "district"
|
|
11
12
|
}
|
|
12
13
|
type AddressFieldType<F extends AddressField> = F extends AddressField.Region ? [F, AddressRegionDb | null] : F extends AddressField.State ? [F, AddressState | null] : F extends AddressField.City ? [F, AddressCity | null] : [F, AddressDistrict | null];
|
|
14
|
+
type AddressFavorType<F extends AddressField> = F extends AddressField.Region | AddressField.State ? string : number;
|
|
13
15
|
/**
|
|
14
16
|
* Address selector props
|
|
15
17
|
*/
|
|
@@ -18,6 +20,10 @@ export type AddressSelectorProps = {
|
|
|
18
20
|
* Address API
|
|
19
21
|
*/
|
|
20
22
|
api: AddressApi;
|
|
23
|
+
/**
|
|
24
|
+
* Break points
|
|
25
|
+
*/
|
|
26
|
+
breakPoints?: RegularBreakpoints;
|
|
21
27
|
/**
|
|
22
28
|
* City
|
|
23
29
|
*/
|
|
@@ -38,6 +44,12 @@ export type AddressSelectorProps = {
|
|
|
38
44
|
* Error
|
|
39
45
|
*/
|
|
40
46
|
error?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Get favored ids
|
|
49
|
+
* @param field Field
|
|
50
|
+
* @returns Result
|
|
51
|
+
*/
|
|
52
|
+
favoredIds?: <F extends AddressField>(field: F) => AddressFavorType<F>[];
|
|
41
53
|
/**
|
|
42
54
|
* The helper text content.
|
|
43
55
|
*/
|
package/lib/AddresSelector.js
CHANGED
|
@@ -22,7 +22,11 @@ export function AddressSelector(props) {
|
|
|
22
22
|
// Labels
|
|
23
23
|
const { city: cityDefault = "City", district: districtDefault = "District", region: regionDefault = "Region", state: stateDefault = "State" } = (_a = globalApp === null || globalApp === void 0 ? void 0 : globalApp.getLabels("region", "state", "city", "district")) !== null && _a !== void 0 ? _a : {};
|
|
24
24
|
// Destruct
|
|
25
|
-
const { api, city, cityLabel = cityDefault, district, districtLabel = districtDefault, error, helperText, hideRegion, label, onChange, region, regionLabel = regionDefault, required, search, state, stateLabel = stateDefault } = props;
|
|
25
|
+
const { api, city, cityLabel = cityDefault, district, districtLabel = districtDefault, error, favoredIds, helperText, hideRegion, label, onChange, region, regionLabel = regionDefault, required, search, state, stateLabel = stateDefault, breakPoints = { xs: 12, md: 6, lg: hideRegion ? 4 : 3 } } = props;
|
|
26
|
+
const isMounted = React.useRef(true);
|
|
27
|
+
React.useEffect(() => () => {
|
|
28
|
+
isMounted.current = false;
|
|
29
|
+
}, []);
|
|
26
30
|
// States
|
|
27
31
|
const [regionState, setRegion] = React.useState(region);
|
|
28
32
|
const [stateState, setState] = React.useState(state);
|
|
@@ -39,8 +43,10 @@ export function AddressSelector(props) {
|
|
|
39
43
|
if (regionState == null)
|
|
40
44
|
setStates([]);
|
|
41
45
|
else
|
|
42
|
-
api
|
|
43
|
-
|
|
46
|
+
api
|
|
47
|
+
.states(regionState, favoredIds == null ? undefined : favoredIds(AddressField.State))
|
|
48
|
+
.then((items) => {
|
|
49
|
+
if (items == null || !isMounted.current)
|
|
44
50
|
return;
|
|
45
51
|
setStates(items);
|
|
46
52
|
});
|
|
@@ -49,8 +55,10 @@ export function AddressSelector(props) {
|
|
|
49
55
|
if (stateState == null)
|
|
50
56
|
setCities([]);
|
|
51
57
|
else
|
|
52
|
-
api
|
|
53
|
-
|
|
58
|
+
api
|
|
59
|
+
.cities(stateState, favoredIds == null ? undefined : favoredIds(AddressField.City))
|
|
60
|
+
.then((items) => {
|
|
61
|
+
if (items == null || !isMounted.current)
|
|
54
62
|
return;
|
|
55
63
|
setCities(items);
|
|
56
64
|
});
|
|
@@ -59,16 +67,18 @@ export function AddressSelector(props) {
|
|
|
59
67
|
if (cityState == null)
|
|
60
68
|
setDistricts([]);
|
|
61
69
|
else
|
|
62
|
-
api
|
|
63
|
-
|
|
70
|
+
api
|
|
71
|
+
.districts(cityState, favoredIds == null ? undefined : favoredIds(AddressField.District))
|
|
72
|
+
.then((items) => {
|
|
73
|
+
if (items == null || !isMounted.current)
|
|
64
74
|
return;
|
|
65
75
|
setDistricts(items);
|
|
66
76
|
});
|
|
67
77
|
}, [cityState]);
|
|
68
|
-
// Field size
|
|
69
|
-
const fieldSize = hideRegion ? 4 : 3;
|
|
70
78
|
// Handle field change
|
|
71
79
|
const handleChange = (event) => {
|
|
80
|
+
if (!isMounted.current)
|
|
81
|
+
return;
|
|
72
82
|
if (onChange)
|
|
73
83
|
onChange(event);
|
|
74
84
|
const [field, data] = event;
|
|
@@ -116,12 +126,19 @@ export function AddressSelector(props) {
|
|
|
116
126
|
return (React.createElement(React.Fragment, null,
|
|
117
127
|
label && (React.createElement(Grid, { item: true, xs: 12 },
|
|
118
128
|
React.createElement(FormLabel, { required: required, sx: { fontSize: (theme) => theme.typography.caption } }, label))),
|
|
119
|
-
!hideRegion && (React.createElement(Grid, { item: true,
|
|
120
|
-
React.createElement(Tiplist, { label: regionLabel, name: AddressField.Region, search: search, fullWidth: true, idValue: regionState, loadData: (keyword, id, items) => api.getRegions({
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
!hideRegion && (React.createElement(Grid, { item: true, ...breakPoints },
|
|
130
|
+
React.createElement(Tiplist, { label: regionLabel, name: AddressField.Region, search: search, fullWidth: true, idValue: regionState, loadData: (keyword, id, items) => api.getRegions({
|
|
131
|
+
keyword,
|
|
132
|
+
id,
|
|
133
|
+
items,
|
|
134
|
+
favoredIds: favoredIds == null
|
|
135
|
+
? undefined
|
|
136
|
+
: favoredIds(AddressField.Region)
|
|
137
|
+
}), inputRequired: required, inputError: error, inputHelperText: helperText, onChange: (_event, value) => handleChange([AddressField.Region, value]) }))),
|
|
138
|
+
React.createElement(Grid, { item: true, ...breakPoints },
|
|
139
|
+
React.createElement(ComboBox, { name: AddressField.State, label: stateLabel, search: search, fullWidth: true, idValue: stateState, options: states, inputRequired: required, inputError: hideRegion ? error : undefined, inputHelperText: hideRegion ? helperText : undefined, onChange: (_event, value) => handleChange([AddressField.State, value]) })),
|
|
140
|
+
React.createElement(Grid, { item: true, ...breakPoints },
|
|
124
141
|
React.createElement(ComboBox, { name: AddressField.City, label: cityLabel, search: search, fullWidth: true, idValue: cityState, options: cities, onChange: (_event, value) => handleChange([AddressField.City, value]) })),
|
|
125
|
-
React.createElement(Grid, { item: true,
|
|
142
|
+
React.createElement(Grid, { item: true, ...breakPoints },
|
|
126
143
|
React.createElement(ComboBox, { name: AddressField.District, label: districtLabel, search: search, fullWidth: true, idValue: districtState, options: districts, onChange: (_event, value) => handleChange([AddressField.District, value]) }))));
|
|
127
144
|
}
|
package/lib/ComboBox.js
CHANGED
|
@@ -13,10 +13,10 @@ import { globalApp } from "./app/ReactApp";
|
|
|
13
13
|
*/
|
|
14
14
|
export function ComboBox(props) {
|
|
15
15
|
// Labels
|
|
16
|
-
const labels = globalApp === null || globalApp === void 0 ? void 0 : globalApp.getLabels("noOptions", "loading");
|
|
16
|
+
const labels = globalApp === null || globalApp === void 0 ? void 0 : globalApp.getLabels("noOptions", "loading", "open");
|
|
17
17
|
// Destruct
|
|
18
18
|
const { search = false, autoAddBlankItem = search, idField = "id", idValue, inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, defaultValue, label, labelField = "label", loadData, onLoadData, name, inputAutoComplete = "new-password", // disable autocomplete and autofill, 'off' does not work
|
|
19
|
-
options, dataReadonly = true, readOnly, onChange, openOnFocus = true, value, disableCloseOnSelect = false, getOptionLabel = (option) => `${option[labelField]}`, sx = { minWidth: "150px" }, noOptionsText = labels === null || labels === void 0 ? void 0 : labels.noOptions, loadingText = labels === null || labels === void 0 ? void 0 : labels.loading, ...rest } = props;
|
|
19
|
+
options, dataReadonly = true, readOnly, onChange, openOnFocus = true, value, disableCloseOnSelect = false, getOptionLabel = (option) => `${option[labelField]}`, sx = { minWidth: "150px" }, noOptionsText = labels === null || labels === void 0 ? void 0 : labels.noOptions, loadingText = labels === null || labels === void 0 ? void 0 : labels.loading, openText = labels === null || labels === void 0 ? void 0 : labels.open, ...rest } = props;
|
|
20
20
|
// Value input ref
|
|
21
21
|
const inputRef = React.createRef();
|
|
22
22
|
// Options state
|
|
@@ -115,5 +115,5 @@ export function ComboBox(props) {
|
|
|
115
115
|
// Custom
|
|
116
116
|
if (onChange != null)
|
|
117
117
|
onChange(event, value, reason, details);
|
|
118
|
-
}, openOnFocus: openOnFocus, sx: sx, renderInput: (params) => search ? (React.createElement(SearchField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })) : (React.createElement(InputField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })), options: localOptions, noOptionsText: noOptionsText, loadingText: loadingText, ...rest })));
|
|
118
|
+
}, openOnFocus: openOnFocus, sx: sx, renderInput: (params) => search ? (React.createElement(SearchField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })) : (React.createElement(InputField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })), options: localOptions, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, ...rest })));
|
|
119
119
|
}
|
package/lib/HiSelector.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { DataTypes, IdDefaultType, LabelDefaultType } from "@etsoo/shared";
|
|
2
|
-
import { SelectChangeEvent } from "@mui/material";
|
|
2
|
+
import { RegularBreakpoints, SelectChangeEvent } from "@mui/material";
|
|
3
3
|
import React from "react";
|
|
4
4
|
/**
|
|
5
5
|
* Hierarchy selector props
|
|
6
6
|
*/
|
|
7
7
|
export type HiSelectorProps<T extends object, D extends DataTypes.Keys<T> = IdDefaultType<T>, L extends DataTypes.Keys<T, string> = LabelDefaultType<T>> = {
|
|
8
|
+
/**
|
|
9
|
+
* Break points
|
|
10
|
+
*/
|
|
11
|
+
breakPoints?: RegularBreakpoints;
|
|
8
12
|
/**
|
|
9
13
|
* Id field
|
|
10
14
|
*/
|
package/lib/HiSelector.js
CHANGED
|
@@ -8,7 +8,7 @@ import { SelectEx } from "./SelectEx";
|
|
|
8
8
|
*/
|
|
9
9
|
export function HiSelector(props) {
|
|
10
10
|
// Destruct
|
|
11
|
-
const { idField = "id", error, helperText, name, label, labelField = "name", loadData, onChange, onSelectChange, onItemChange, required, search = true, values = [] } = props;
|
|
11
|
+
const { breakPoints = { xs: 6, md: 4, lg: 3 }, idField = "id", error, helperText, name, label, labelField = "name", loadData, onChange, onSelectChange, onItemChange, required, search = true, values = [] } = props;
|
|
12
12
|
const [localValues, setValues] = React.useState(values);
|
|
13
13
|
const updateValue = (value) => {
|
|
14
14
|
if (onChange)
|
|
@@ -43,12 +43,12 @@ export function HiSelector(props) {
|
|
|
43
43
|
label && (React.createElement(Grid, { item: true, xs: 12 },
|
|
44
44
|
React.createElement(FormLabel, { required: required, sx: { fontSize: (theme) => theme.typography.caption } }, label))),
|
|
45
45
|
React.createElement("input", { type: "hidden", name: name, value: `${currentValue !== null && currentValue !== void 0 ? currentValue : ""}` }),
|
|
46
|
-
React.createElement(Grid, { item: true,
|
|
46
|
+
React.createElement(Grid, { item: true, ...breakPoints },
|
|
47
47
|
React.createElement(SelectEx, { idField: idField, labelField: labelField, name: "tab1", search: search, fullWidth: true, loadData: () => loadData(), value: values[0], onChange: (event) => doChange(event, 0), onItemChange: doItemChange, inputRequired: required, error: error, helperText: helperText })),
|
|
48
|
-
localValues[0] != null && (React.createElement(Grid, { item: true,
|
|
48
|
+
localValues[0] != null && (React.createElement(Grid, { item: true, ...breakPoints },
|
|
49
49
|
React.createElement(SelectEx, { key: `${localValues[0]}`, idField: idField, labelField: labelField, name: "tab2", search: search, fullWidth: true, loadData: () => loadData(localValues[0]), value: values[1], onChange: (event) => doChange(event, 1), onItemChange: doItemChange }))),
|
|
50
|
-
localValues[1] != null && (React.createElement(Grid, { item: true,
|
|
50
|
+
localValues[1] != null && (React.createElement(Grid, { item: true, ...breakPoints },
|
|
51
51
|
React.createElement(SelectEx, { key: `${localValues[1]}`, idField: idField, labelField: labelField, name: "tab3", search: search, fullWidth: true, loadData: () => loadData(localValues[1]), value: values[2], onChange: (event) => doChange(event, 2), onItemChange: doItemChange }))),
|
|
52
|
-
localValues[2] != null && (React.createElement(Grid, { item: true,
|
|
52
|
+
localValues[2] != null && (React.createElement(Grid, { item: true, ...breakPoints },
|
|
53
53
|
React.createElement(SelectEx, { key: `${localValues[2]}`, idField: idField, labelField: labelField, name: "tab4", search: search, fullWidth: true, loadData: () => loadData(localValues[2]), value: values[3], onChange: (event) => doChange(event, 3), onItemChange: doItemChange })))));
|
|
54
54
|
}
|
package/lib/HiSelectorTL.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { DataTypes, IdDefaultType } from "@etsoo/shared";
|
|
2
|
-
import { AutocompleteChangeReason } from "@mui/material";
|
|
2
|
+
import { AutocompleteChangeReason, RegularBreakpoints } from "@mui/material";
|
|
3
3
|
import React from "react";
|
|
4
4
|
/**
|
|
5
5
|
* Hierarchy tiplist selector props
|
|
6
6
|
*/
|
|
7
7
|
export type HiSelectorTLProps<T extends object, D extends DataTypes.Keys<T> = IdDefaultType<T>> = {
|
|
8
|
+
/**
|
|
9
|
+
* Break points
|
|
10
|
+
*/
|
|
11
|
+
breakPoints?: RegularBreakpoints;
|
|
8
12
|
/**
|
|
9
13
|
* Id field
|
|
10
14
|
*/
|
package/lib/HiSelectorTL.js
CHANGED
|
@@ -8,7 +8,7 @@ import { Tiplist } from "./Tiplist";
|
|
|
8
8
|
*/
|
|
9
9
|
export function HiSelectorTL(props) {
|
|
10
10
|
// Destruct
|
|
11
|
-
const { idField = "id", error, helperText, name, label = name, loadData, onChange, onItemChange, required, search = false, values = [] } = props;
|
|
11
|
+
const { breakPoints = { xs: 6, md: 4, lg: 3 }, idField = "id", error, helperText, name, label = name, loadData, onChange, onItemChange, required, search = false, values = [] } = props;
|
|
12
12
|
const [localValues, setValues] = React.useState(values);
|
|
13
13
|
const updateValue = (value) => {
|
|
14
14
|
if (onChange)
|
|
@@ -38,12 +38,12 @@ export function HiSelectorTL(props) {
|
|
|
38
38
|
label && (React.createElement(Grid, { item: true, xs: 12 },
|
|
39
39
|
React.createElement(FormLabel, { required: required, sx: { fontSize: (theme) => theme.typography.caption } }, label))),
|
|
40
40
|
React.createElement("input", { type: "hidden", name: name, value: `${currentValue !== null && currentValue !== void 0 ? currentValue : ""}` }),
|
|
41
|
-
React.createElement(Grid, { item: true,
|
|
41
|
+
React.createElement(Grid, { item: true, ...breakPoints },
|
|
42
42
|
React.createElement(Tiplist, { idField: idField, label: "1", name: "tab1", search: search, fullWidth: true, idValue: values[0], loadData: (keyword, id, items) => loadData(keyword, id, items), inputRequired: required, inputError: error, inputHelperText: helperText, onChange: (event, value, reason) => doChange(0, event, value, reason) })),
|
|
43
|
-
localValues[0] != null && (React.createElement(Grid, { item: true,
|
|
43
|
+
localValues[0] != null && (React.createElement(Grid, { item: true, ...breakPoints },
|
|
44
44
|
React.createElement(Tiplist, { key: `${localValues[0]}`, label: "2", idField: idField, name: "tab2", search: search, fullWidth: true, loadData: (keyword, id, items) => loadData(keyword, id, items, localValues[0]), idValue: values[1], onChange: (event, value, reason) => doChange(1, event, value, reason) }))),
|
|
45
|
-
localValues[1] != null && (React.createElement(Grid, { item: true,
|
|
45
|
+
localValues[1] != null && (React.createElement(Grid, { item: true, ...breakPoints },
|
|
46
46
|
React.createElement(Tiplist, { key: `${localValues[1]}`, label: "3", idField: idField, name: "tab3", search: search, fullWidth: true, loadData: (keyword, id, items) => loadData(keyword, id, items, localValues[1]), idValue: values[2], onChange: (event, value, reason) => doChange(2, event, value, reason) }))),
|
|
47
|
-
localValues[2] != null && (React.createElement(Grid, { item: true,
|
|
47
|
+
localValues[2] != null && (React.createElement(Grid, { item: true, ...breakPoints },
|
|
48
48
|
React.createElement(Tiplist, { key: `${localValues[2]}`, label: "4", idField: idField, name: "tab4", search: search, fullWidth: true, loadData: (keyword, id, items) => loadData(keyword, id, items, localValues[2]), idValue: values[3], onChange: (event, value, reason) => doChange(3, event, value, reason) })))));
|
|
49
49
|
}
|
package/lib/Tiplist.js
CHANGED
|
@@ -13,9 +13,9 @@ import { SearchField } from "./SearchField";
|
|
|
13
13
|
export function Tiplist(props) {
|
|
14
14
|
var _a;
|
|
15
15
|
// Labels
|
|
16
|
-
const { noOptions, loading, more } = (_a = globalApp === null || globalApp === void 0 ? void 0 : globalApp.getLabels("noOptions", "loading", "more")) !== null && _a !== void 0 ? _a : {};
|
|
16
|
+
const { noOptions, loading, more, open: openDefault } = (_a = globalApp === null || globalApp === void 0 ? void 0 : globalApp.getLabels("noOptions", "loading", "more", "open")) !== null && _a !== void 0 ? _a : {};
|
|
17
17
|
// Destruct
|
|
18
|
-
const { search = false, idField = "id", idValue, inputAutoComplete = "new-password", inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, label, loadData, defaultValue, value, maxItems = 16, name, readOnly, onChange, openOnFocus = true, sx = { minWidth: "180px" }, noOptionsText = noOptions, loadingText = loading, getOptionLabel, getOptionDisabled, ...rest } = props;
|
|
18
|
+
const { search = false, idField = "id", idValue, inputAutoComplete = "new-password", inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, label, loadData, defaultValue, value, maxItems = 16, name, readOnly, onChange, openOnFocus = true, sx = { minWidth: "180px" }, noOptionsText = noOptions, loadingText = loading, openText = openDefault, getOptionLabel, getOptionDisabled, ...rest } = props;
|
|
19
19
|
// Value input ref
|
|
20
20
|
const inputRef = React.createRef();
|
|
21
21
|
// Local value
|
|
@@ -156,7 +156,7 @@ export function Tiplist(props) {
|
|
|
156
156
|
open: false,
|
|
157
157
|
...(!states.value && { options: [] })
|
|
158
158
|
});
|
|
159
|
-
}, loading: states.loading, sx: sx, renderInput: (params) => search ? (React.createElement(SearchField, { onChange: changeHandle, ...addReadOnly(params), readOnly: readOnly, label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })) : (React.createElement(InputField, { onChange: changeHandle, ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })), isOptionEqualToValue: (option, value) => option[idField] === value[idField], noOptionsText: noOptionsText, loadingText: loadingText, getOptionDisabled: (item) => {
|
|
159
|
+
}, loading: states.loading, sx: sx, renderInput: (params) => search ? (React.createElement(SearchField, { onChange: changeHandle, ...addReadOnly(params), readOnly: readOnly, label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })) : (React.createElement(InputField, { onChange: changeHandle, ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })), isOptionEqualToValue: (option, value) => option[idField] === value[idField], noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionDisabled: (item) => {
|
|
160
160
|
if (item[idField] === "n/a")
|
|
161
161
|
return true;
|
|
162
162
|
return getOptionDisabled ? getOptionDisabled(item) : false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.47",
|
|
4
4
|
"description": "TypeScript Material-UI Implementation",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"@emotion/css": "^11.10.6",
|
|
51
51
|
"@emotion/react": "^11.10.6",
|
|
52
52
|
"@emotion/styled": "^11.10.6",
|
|
53
|
-
"@etsoo/appscript": "^1.3.
|
|
53
|
+
"@etsoo/appscript": "^1.3.71",
|
|
54
54
|
"@etsoo/notificationbase": "^1.1.24",
|
|
55
|
-
"@etsoo/react": "^1.6.
|
|
56
|
-
"@etsoo/shared": "^1.1.
|
|
57
|
-
"@mui/icons-material": "^5.11.
|
|
58
|
-
"@mui/material": "^5.11.
|
|
59
|
-
"@mui/x-data-grid": "^6.0.
|
|
55
|
+
"@etsoo/react": "^1.6.50",
|
|
56
|
+
"@etsoo/shared": "^1.1.90",
|
|
57
|
+
"@mui/icons-material": "^5.11.11",
|
|
58
|
+
"@mui/material": "^5.11.12",
|
|
59
|
+
"@mui/x-data-grid": "^6.0.1",
|
|
60
60
|
"@types/pica": "^9.0.1",
|
|
61
61
|
"@types/pulltorefreshjs": "^0.1.5",
|
|
62
62
|
"@types/react": "^18.0.28",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"react-dom": "^18.2.0",
|
|
72
72
|
"react-draggable": "^4.4.5",
|
|
73
73
|
"react-imask": "^6.4.3",
|
|
74
|
-
"react-router-dom": "^6.8.
|
|
74
|
+
"react-router-dom": "^6.8.2",
|
|
75
75
|
"react-window": "^1.8.8"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
@@ -85,10 +85,10 @@
|
|
|
85
85
|
"@testing-library/jest-dom": "^5.16.5",
|
|
86
86
|
"@testing-library/react": "^14.0.0",
|
|
87
87
|
"@types/jest": "^29.4.0",
|
|
88
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
89
|
-
"@typescript-eslint/parser": "^5.
|
|
90
|
-
"jest": "^29.
|
|
91
|
-
"jest-environment-jsdom": "^29.
|
|
88
|
+
"@typescript-eslint/eslint-plugin": "^5.54.1",
|
|
89
|
+
"@typescript-eslint/parser": "^5.54.1",
|
|
90
|
+
"jest": "^29.5.0",
|
|
91
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
92
92
|
"typescript": "^4.9.5"
|
|
93
93
|
}
|
|
94
94
|
}
|
package/src/AddresSelector.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
AddressRegionDb,
|
|
6
6
|
AddressState
|
|
7
7
|
} from "@etsoo/appscript";
|
|
8
|
-
import { FormLabel, Grid } from "@mui/material";
|
|
8
|
+
import { FormLabel, Grid, RegularBreakpoints } from "@mui/material";
|
|
9
9
|
import React from "react";
|
|
10
10
|
import { globalApp } from "./app/ReactApp";
|
|
11
11
|
import { ComboBox } from "./ComboBox";
|
|
@@ -29,6 +29,12 @@ type AddressFieldType<F extends AddressField> = F extends AddressField.Region
|
|
|
29
29
|
? [F, AddressCity | null]
|
|
30
30
|
: [F, AddressDistrict | null];
|
|
31
31
|
|
|
32
|
+
type AddressFavorType<F extends AddressField> = F extends
|
|
33
|
+
| AddressField.Region
|
|
34
|
+
| AddressField.State
|
|
35
|
+
? string
|
|
36
|
+
: number;
|
|
37
|
+
|
|
32
38
|
/**
|
|
33
39
|
* Address selector props
|
|
34
40
|
*/
|
|
@@ -38,6 +44,11 @@ export type AddressSelectorProps = {
|
|
|
38
44
|
*/
|
|
39
45
|
api: AddressApi;
|
|
40
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Break points
|
|
49
|
+
*/
|
|
50
|
+
breakPoints?: RegularBreakpoints;
|
|
51
|
+
|
|
41
52
|
/**
|
|
42
53
|
* City
|
|
43
54
|
*/
|
|
@@ -63,6 +74,13 @@ export type AddressSelectorProps = {
|
|
|
63
74
|
*/
|
|
64
75
|
error?: boolean;
|
|
65
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Get favored ids
|
|
79
|
+
* @param field Field
|
|
80
|
+
* @returns Result
|
|
81
|
+
*/
|
|
82
|
+
favoredIds?: <F extends AddressField>(field: F) => AddressFavorType<F>[];
|
|
83
|
+
|
|
66
84
|
/**
|
|
67
85
|
* The helper text content.
|
|
68
86
|
*/
|
|
@@ -136,6 +154,7 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
136
154
|
district,
|
|
137
155
|
districtLabel = districtDefault,
|
|
138
156
|
error,
|
|
157
|
+
favoredIds,
|
|
139
158
|
helperText,
|
|
140
159
|
hideRegion,
|
|
141
160
|
label,
|
|
@@ -145,9 +164,18 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
145
164
|
required,
|
|
146
165
|
search,
|
|
147
166
|
state,
|
|
148
|
-
stateLabel = stateDefault
|
|
167
|
+
stateLabel = stateDefault,
|
|
168
|
+
breakPoints = { xs: 12, md: 6, lg: hideRegion ? 4 : 3 }
|
|
149
169
|
} = props;
|
|
150
170
|
|
|
171
|
+
const isMounted = React.useRef(true);
|
|
172
|
+
React.useEffect(
|
|
173
|
+
() => () => {
|
|
174
|
+
isMounted.current = false;
|
|
175
|
+
},
|
|
176
|
+
[]
|
|
177
|
+
);
|
|
178
|
+
|
|
151
179
|
// States
|
|
152
180
|
const [regionState, setRegion] = React.useState(region);
|
|
153
181
|
const [stateState, setState] = React.useState(state);
|
|
@@ -166,33 +194,47 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
166
194
|
React.useEffect(() => {
|
|
167
195
|
if (regionState == null) setStates([]);
|
|
168
196
|
else
|
|
169
|
-
api
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
197
|
+
api
|
|
198
|
+
.states(
|
|
199
|
+
regionState,
|
|
200
|
+
favoredIds == null ? undefined : favoredIds(AddressField.State)
|
|
201
|
+
)
|
|
202
|
+
.then((items) => {
|
|
203
|
+
if (items == null || !isMounted.current) return;
|
|
204
|
+
setStates(items);
|
|
205
|
+
});
|
|
173
206
|
}, [regionState]);
|
|
174
207
|
React.useEffect(() => {
|
|
175
208
|
if (stateState == null) setCities([]);
|
|
176
209
|
else
|
|
177
|
-
api
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
210
|
+
api
|
|
211
|
+
.cities(
|
|
212
|
+
stateState,
|
|
213
|
+
favoredIds == null ? undefined : favoredIds(AddressField.City)
|
|
214
|
+
)
|
|
215
|
+
.then((items) => {
|
|
216
|
+
if (items == null || !isMounted.current) return;
|
|
217
|
+
setCities(items);
|
|
218
|
+
});
|
|
181
219
|
}, [stateState]);
|
|
182
220
|
React.useEffect(() => {
|
|
183
221
|
if (cityState == null) setDistricts([]);
|
|
184
222
|
else
|
|
185
|
-
api
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
223
|
+
api
|
|
224
|
+
.districts(
|
|
225
|
+
cityState,
|
|
226
|
+
favoredIds == null ? undefined : favoredIds(AddressField.District)
|
|
227
|
+
)
|
|
228
|
+
.then((items) => {
|
|
229
|
+
if (items == null || !isMounted.current) return;
|
|
230
|
+
setDistricts(items);
|
|
231
|
+
});
|
|
189
232
|
}, [cityState]);
|
|
190
233
|
|
|
191
|
-
// Field size
|
|
192
|
-
const fieldSize = hideRegion ? 4 : 3;
|
|
193
|
-
|
|
194
234
|
// Handle field change
|
|
195
235
|
const handleChange = <F extends AddressField>(event: AddressFieldType<F>) => {
|
|
236
|
+
if (!isMounted.current) return;
|
|
237
|
+
|
|
196
238
|
if (onChange) onChange(event);
|
|
197
239
|
|
|
198
240
|
const [field, data] = event;
|
|
@@ -254,7 +296,7 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
254
296
|
</Grid>
|
|
255
297
|
)}
|
|
256
298
|
{!hideRegion && (
|
|
257
|
-
<Grid item
|
|
299
|
+
<Grid item {...breakPoints}>
|
|
258
300
|
<Tiplist<AddressRegionDb>
|
|
259
301
|
label={regionLabel}
|
|
260
302
|
name={AddressField.Region}
|
|
@@ -262,7 +304,15 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
262
304
|
fullWidth
|
|
263
305
|
idValue={regionState}
|
|
264
306
|
loadData={(keyword, id, items) =>
|
|
265
|
-
api.getRegions({
|
|
307
|
+
api.getRegions({
|
|
308
|
+
keyword,
|
|
309
|
+
id,
|
|
310
|
+
items,
|
|
311
|
+
favoredIds:
|
|
312
|
+
favoredIds == null
|
|
313
|
+
? undefined
|
|
314
|
+
: favoredIds(AddressField.Region)
|
|
315
|
+
})
|
|
266
316
|
}
|
|
267
317
|
inputRequired={required}
|
|
268
318
|
inputError={error}
|
|
@@ -273,7 +323,7 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
273
323
|
/>
|
|
274
324
|
</Grid>
|
|
275
325
|
)}
|
|
276
|
-
<Grid item
|
|
326
|
+
<Grid item {...breakPoints}>
|
|
277
327
|
<ComboBox<AddressState>
|
|
278
328
|
name={AddressField.State}
|
|
279
329
|
label={stateLabel}
|
|
@@ -281,7 +331,7 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
281
331
|
fullWidth
|
|
282
332
|
idValue={stateState}
|
|
283
333
|
options={states}
|
|
284
|
-
inputRequired={
|
|
334
|
+
inputRequired={required}
|
|
285
335
|
inputError={hideRegion ? error : undefined}
|
|
286
336
|
inputHelperText={hideRegion ? helperText : undefined}
|
|
287
337
|
onChange={(_event, value) =>
|
|
@@ -289,7 +339,7 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
289
339
|
}
|
|
290
340
|
/>
|
|
291
341
|
</Grid>
|
|
292
|
-
<Grid item
|
|
342
|
+
<Grid item {...breakPoints}>
|
|
293
343
|
<ComboBox<AddressCity>
|
|
294
344
|
name={AddressField.City}
|
|
295
345
|
label={cityLabel}
|
|
@@ -300,7 +350,7 @@ export function AddressSelector(props: AddressSelectorProps) {
|
|
|
300
350
|
onChange={(_event, value) => handleChange([AddressField.City, value])}
|
|
301
351
|
/>
|
|
302
352
|
</Grid>
|
|
303
|
-
<Grid item
|
|
353
|
+
<Grid item {...breakPoints}>
|
|
304
354
|
<ComboBox<AddressDistrict>
|
|
305
355
|
name={AddressField.District}
|
|
306
356
|
label={districtLabel}
|
package/src/ComboBox.tsx
CHANGED
|
@@ -64,7 +64,7 @@ export function ComboBox<
|
|
|
64
64
|
L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
|
|
65
65
|
>(props: ComboBoxProps<T, D, L>) {
|
|
66
66
|
// Labels
|
|
67
|
-
const labels = globalApp?.getLabels("noOptions", "loading");
|
|
67
|
+
const labels = globalApp?.getLabels("noOptions", "loading", "open");
|
|
68
68
|
|
|
69
69
|
// Destruct
|
|
70
70
|
const {
|
|
@@ -96,6 +96,7 @@ export function ComboBox<
|
|
|
96
96
|
sx = { minWidth: "150px" },
|
|
97
97
|
noOptionsText = labels?.noOptions,
|
|
98
98
|
loadingText = labels?.loading,
|
|
99
|
+
openText = labels?.open,
|
|
99
100
|
...rest
|
|
100
101
|
} = props;
|
|
101
102
|
|
|
@@ -262,6 +263,7 @@ export function ComboBox<
|
|
|
262
263
|
options={localOptions}
|
|
263
264
|
noOptionsText={noOptionsText}
|
|
264
265
|
loadingText={loadingText}
|
|
266
|
+
openText={openText}
|
|
265
267
|
{...rest}
|
|
266
268
|
/>
|
|
267
269
|
</div>
|
package/src/HiSelector.tsx
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { DataTypes, IdDefaultType, LabelDefaultType } from "@etsoo/shared";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
FormLabel,
|
|
4
|
+
Grid,
|
|
5
|
+
RegularBreakpoints,
|
|
6
|
+
SelectChangeEvent
|
|
7
|
+
} from "@mui/material";
|
|
3
8
|
import React from "react";
|
|
4
9
|
import { SelectEx } from "./SelectEx";
|
|
5
10
|
|
|
@@ -11,6 +16,11 @@ export type HiSelectorProps<
|
|
|
11
16
|
D extends DataTypes.Keys<T> = IdDefaultType<T>,
|
|
12
17
|
L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
|
|
13
18
|
> = {
|
|
19
|
+
/**
|
|
20
|
+
* Break points
|
|
21
|
+
*/
|
|
22
|
+
breakPoints?: RegularBreakpoints;
|
|
23
|
+
|
|
14
24
|
/**
|
|
15
25
|
* Id field
|
|
16
26
|
*/
|
|
@@ -89,6 +99,7 @@ export function HiSelector<
|
|
|
89
99
|
>(props: HiSelectorProps<T, D, L>) {
|
|
90
100
|
// Destruct
|
|
91
101
|
const {
|
|
102
|
+
breakPoints = { xs: 6, md: 4, lg: 3 },
|
|
92
103
|
idField = "id" as D,
|
|
93
104
|
error,
|
|
94
105
|
helperText,
|
|
@@ -153,7 +164,7 @@ export function HiSelector<
|
|
|
153
164
|
</Grid>
|
|
154
165
|
)}
|
|
155
166
|
<input type="hidden" name={name} value={`${currentValue ?? ""}`} />
|
|
156
|
-
<Grid item
|
|
167
|
+
<Grid item {...breakPoints}>
|
|
157
168
|
<SelectEx<T, D, L>
|
|
158
169
|
idField={idField}
|
|
159
170
|
labelField={labelField}
|
|
@@ -170,7 +181,7 @@ export function HiSelector<
|
|
|
170
181
|
/>
|
|
171
182
|
</Grid>
|
|
172
183
|
{localValues[0] != null && (
|
|
173
|
-
<Grid item
|
|
184
|
+
<Grid item {...breakPoints}>
|
|
174
185
|
<SelectEx<T, D, L>
|
|
175
186
|
key={`${localValues[0]}`}
|
|
176
187
|
idField={idField}
|
|
@@ -186,7 +197,7 @@ export function HiSelector<
|
|
|
186
197
|
</Grid>
|
|
187
198
|
)}
|
|
188
199
|
{localValues[1] != null && (
|
|
189
|
-
<Grid item
|
|
200
|
+
<Grid item {...breakPoints}>
|
|
190
201
|
<SelectEx<T, D, L>
|
|
191
202
|
key={`${localValues[1]}`}
|
|
192
203
|
idField={idField}
|
|
@@ -202,7 +213,7 @@ export function HiSelector<
|
|
|
202
213
|
</Grid>
|
|
203
214
|
)}
|
|
204
215
|
{localValues[2] != null && (
|
|
205
|
-
<Grid item
|
|
216
|
+
<Grid item {...breakPoints}>
|
|
206
217
|
<SelectEx<T, D, L>
|
|
207
218
|
key={`${localValues[2]}`}
|
|
208
219
|
idField={idField}
|
package/src/HiSelectorTL.tsx
CHANGED
|
@@ -3,7 +3,8 @@ import {
|
|
|
3
3
|
AutocompleteChangeReason,
|
|
4
4
|
AutocompleteValue,
|
|
5
5
|
FormLabel,
|
|
6
|
-
Grid
|
|
6
|
+
Grid,
|
|
7
|
+
RegularBreakpoints
|
|
7
8
|
} from "@mui/material";
|
|
8
9
|
import React from "react";
|
|
9
10
|
import { Tiplist } from "./Tiplist";
|
|
@@ -15,6 +16,11 @@ export type HiSelectorTLProps<
|
|
|
15
16
|
T extends object,
|
|
16
17
|
D extends DataTypes.Keys<T> = IdDefaultType<T>
|
|
17
18
|
> = {
|
|
19
|
+
/**
|
|
20
|
+
* Break points
|
|
21
|
+
*/
|
|
22
|
+
breakPoints?: RegularBreakpoints;
|
|
23
|
+
|
|
18
24
|
/**
|
|
19
25
|
* Id field
|
|
20
26
|
*/
|
|
@@ -91,6 +97,7 @@ export function HiSelectorTL<
|
|
|
91
97
|
>(props: HiSelectorTLProps<T, D>) {
|
|
92
98
|
// Destruct
|
|
93
99
|
const {
|
|
100
|
+
breakPoints = { xs: 6, md: 4, lg: 3 },
|
|
94
101
|
idField = "id" as D,
|
|
95
102
|
error,
|
|
96
103
|
helperText,
|
|
@@ -153,7 +160,7 @@ export function HiSelectorTL<
|
|
|
153
160
|
</Grid>
|
|
154
161
|
)}
|
|
155
162
|
<input type="hidden" name={name} value={`${currentValue ?? ""}`} />
|
|
156
|
-
<Grid item
|
|
163
|
+
<Grid item {...breakPoints}>
|
|
157
164
|
<Tiplist<T, D>
|
|
158
165
|
idField={idField}
|
|
159
166
|
label="1"
|
|
@@ -169,7 +176,7 @@ export function HiSelectorTL<
|
|
|
169
176
|
/>
|
|
170
177
|
</Grid>
|
|
171
178
|
{localValues[0] != null && (
|
|
172
|
-
<Grid item
|
|
179
|
+
<Grid item {...breakPoints}>
|
|
173
180
|
<Tiplist<T, D>
|
|
174
181
|
key={`${localValues[0]}`}
|
|
175
182
|
label="2"
|
|
@@ -188,7 +195,7 @@ export function HiSelectorTL<
|
|
|
188
195
|
</Grid>
|
|
189
196
|
)}
|
|
190
197
|
{localValues[1] != null && (
|
|
191
|
-
<Grid item
|
|
198
|
+
<Grid item {...breakPoints}>
|
|
192
199
|
<Tiplist<T, D>
|
|
193
200
|
key={`${localValues[1]}`}
|
|
194
201
|
label="3"
|
|
@@ -207,7 +214,7 @@ export function HiSelectorTL<
|
|
|
207
214
|
</Grid>
|
|
208
215
|
)}
|
|
209
216
|
{localValues[2] != null && (
|
|
210
|
-
<Grid item
|
|
217
|
+
<Grid item {...breakPoints}>
|
|
211
218
|
<Tiplist<T, D>
|
|
212
219
|
key={`${localValues[2]}`}
|
|
213
220
|
label="4"
|
package/src/Tiplist.tsx
CHANGED
|
@@ -47,8 +47,12 @@ export function Tiplist<
|
|
|
47
47
|
D extends DataTypes.Keys<T> = IdDefaultType<T>
|
|
48
48
|
>(props: TiplistProps<T, D>) {
|
|
49
49
|
// Labels
|
|
50
|
-
const {
|
|
51
|
-
|
|
50
|
+
const {
|
|
51
|
+
noOptions,
|
|
52
|
+
loading,
|
|
53
|
+
more,
|
|
54
|
+
open: openDefault
|
|
55
|
+
} = globalApp?.getLabels("noOptions", "loading", "more", "open") ?? {};
|
|
52
56
|
|
|
53
57
|
// Destruct
|
|
54
58
|
const {
|
|
@@ -74,6 +78,7 @@ export function Tiplist<
|
|
|
74
78
|
sx = { minWidth: "180px" },
|
|
75
79
|
noOptionsText = noOptions,
|
|
76
80
|
loadingText = loading,
|
|
81
|
+
openText = openDefault,
|
|
77
82
|
getOptionLabel,
|
|
78
83
|
getOptionDisabled,
|
|
79
84
|
...rest
|
|
@@ -313,6 +318,7 @@ export function Tiplist<
|
|
|
313
318
|
}
|
|
314
319
|
noOptionsText={noOptionsText}
|
|
315
320
|
loadingText={loadingText}
|
|
321
|
+
openText={openText}
|
|
316
322
|
getOptionDisabled={(item) => {
|
|
317
323
|
if (item[idField] === "n/a") return true;
|
|
318
324
|
return getOptionDisabled ? getOptionDisabled(item) : false;
|