@etsoo/materialui 1.1.46 → 1.1.48

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.
@@ -11,6 +11,7 @@ export declare enum AddressField {
11
11
  District = "district"
12
12
  }
13
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;
14
15
  /**
15
16
  * Address selector props
16
17
  */
@@ -43,6 +44,12 @@ export type AddressSelectorProps = {
43
44
  * Error
44
45
  */
45
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>[];
46
53
  /**
47
54
  * The helper text content.
48
55
  */
@@ -22,7 +22,7 @@ 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, breakPoints = { xs: 12, md: 6, lg: hideRegion ? 4 : 3 } } = 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
26
  const isMounted = React.useRef(true);
27
27
  React.useEffect(() => () => {
28
28
  isMounted.current = false;
@@ -43,7 +43,9 @@ export function AddressSelector(props) {
43
43
  if (regionState == null)
44
44
  setStates([]);
45
45
  else
46
- api.states(regionState).then((items) => {
46
+ api
47
+ .states(regionState, favoredIds == null ? undefined : favoredIds(AddressField.State))
48
+ .then((items) => {
47
49
  if (items == null || !isMounted.current)
48
50
  return;
49
51
  setStates(items);
@@ -53,7 +55,9 @@ export function AddressSelector(props) {
53
55
  if (stateState == null)
54
56
  setCities([]);
55
57
  else
56
- api.cities(stateState).then((items) => {
58
+ api
59
+ .cities(stateState, favoredIds == null ? undefined : favoredIds(AddressField.City))
60
+ .then((items) => {
57
61
  if (items == null || !isMounted.current)
58
62
  return;
59
63
  setCities(items);
@@ -63,7 +67,9 @@ export function AddressSelector(props) {
63
67
  if (cityState == null)
64
68
  setDistricts([]);
65
69
  else
66
- api.districts(cityState).then((items) => {
70
+ api
71
+ .districts(cityState, favoredIds == null ? undefined : favoredIds(AddressField.District))
72
+ .then((items) => {
67
73
  if (items == null || !isMounted.current)
68
74
  return;
69
75
  setDistricts(items);
@@ -121,9 +127,16 @@ export function AddressSelector(props) {
121
127
  label && (React.createElement(Grid, { item: true, xs: 12 },
122
128
  React.createElement(FormLabel, { required: required, sx: { fontSize: (theme) => theme.typography.caption } }, label))),
123
129
  !hideRegion && (React.createElement(Grid, { item: true, ...breakPoints },
124
- React.createElement(Tiplist, { label: regionLabel, name: AddressField.Region, search: search, fullWidth: true, idValue: regionState, loadData: (keyword, id, items) => api.getRegions({ keyword, id, items }), inputRequired: required, inputError: error, inputHelperText: helperText, onChange: (_event, value) => handleChange([AddressField.Region, value]) }))),
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]) }))),
125
138
  React.createElement(Grid, { item: true, ...breakPoints },
126
- React.createElement(ComboBox, { name: AddressField.State, label: stateLabel, search: search, fullWidth: true, idValue: stateState, options: states, inputRequired: hideRegion ? required : undefined, inputError: hideRegion ? error : undefined, inputHelperText: hideRegion ? helperText : undefined, onChange: (_event, value) => handleChange([AddressField.State, value]) })),
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]) })),
127
140
  React.createElement(Grid, { item: true, ...breakPoints },
128
141
  React.createElement(ComboBox, { name: AddressField.City, label: cityLabel, search: search, fullWidth: true, idValue: cityState, options: cities, onChange: (_event, value) => handleChange([AddressField.City, value]) })),
129
142
  React.createElement(Grid, { item: true, ...breakPoints },
@@ -1,5 +1,5 @@
1
- import { TextFieldProps } from '@mui/material';
2
- import React from 'react';
1
+ import { TextFieldProps } from "@mui/material";
2
+ import React from "react";
3
3
  /**
4
4
  * Input field props
5
5
  */
@@ -8,6 +8,10 @@ export type InputFieldProps = TextFieldProps & {
8
8
  * Change delay (ms) to avoid repeatly dispatch onChange
9
9
  */
10
10
  changeDelay?: number;
11
+ /**
12
+ * Change delay handler, without it onChange will be applied
13
+ */
14
+ onChangeDelay?: React.ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement>;
11
15
  /**
12
16
  * Is the field read only?
13
17
  */
@@ -23,6 +27,10 @@ export declare const InputField: React.ForwardRefExoticComponent<(Omit<import("@
23
27
  * Change delay (ms) to avoid repeatly dispatch onChange
24
28
  */
25
29
  changeDelay?: number | undefined;
30
+ /**
31
+ * Change delay handler, without it onChange will be applied
32
+ */
33
+ onChangeDelay?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
26
34
  /**
27
35
  * Is the field read only?
28
36
  */
@@ -32,6 +40,10 @@ export declare const InputField: React.ForwardRefExoticComponent<(Omit<import("@
32
40
  * Change delay (ms) to avoid repeatly dispatch onChange
33
41
  */
34
42
  changeDelay?: number | undefined;
43
+ /**
44
+ * Change delay handler, without it onChange will be applied
45
+ */
46
+ onChangeDelay?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
35
47
  /**
36
48
  * Is the field read only?
37
49
  */
@@ -41,6 +53,10 @@ export declare const InputField: React.ForwardRefExoticComponent<(Omit<import("@
41
53
  * Change delay (ms) to avoid repeatly dispatch onChange
42
54
  */
43
55
  changeDelay?: number | undefined;
56
+ /**
57
+ * Change delay handler, without it onChange will be applied
58
+ */
59
+ onChangeDelay?: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement> | undefined;
44
60
  /**
45
61
  * Is the field read only?
46
62
  */
package/lib/InputField.js CHANGED
@@ -1,7 +1,7 @@
1
- import { useDelayedExecutor } from '@etsoo/react';
2
- import { TextField } from '@mui/material';
3
- import React from 'react';
4
- import { MUGlobal } from './MUGlobal';
1
+ import { useDelayedExecutor } from "@etsoo/react";
2
+ import { TextField } from "@mui/material";
3
+ import React from "react";
4
+ import { MUGlobal } from "./MUGlobal";
5
5
  /**
6
6
  * Input field
7
7
  * @param props Props
@@ -10,23 +10,25 @@ import { MUGlobal } from './MUGlobal';
10
10
  export const InputField = React.forwardRef((props, ref) => {
11
11
  var _a;
12
12
  // Destruct
13
- const { changeDelay, InputLabelProps = {}, InputProps = {}, onChange, readOnly, size = MUGlobal.inputFieldSize, variant = MUGlobal.inputFieldVariant, ...rest } = props;
13
+ const { changeDelay, InputLabelProps = {}, InputProps = {}, onChange, onChangeDelay, readOnly, size = MUGlobal.inputFieldSize, variant = MUGlobal.inputFieldVariant, ...rest } = props;
14
14
  // Shrink
15
15
  (_a = InputLabelProps.shrink) !== null && _a !== void 0 ? _a : (InputLabelProps.shrink = MUGlobal.searchFieldShrink);
16
16
  // Read only
17
17
  if (readOnly != null)
18
18
  InputProps.readOnly = readOnly;
19
19
  const isMounted = React.useRef(true);
20
- const delayed = onChange != null && changeDelay != null && changeDelay >= 1
21
- ? useDelayedExecutor(onChange, changeDelay)
22
- : undefined;
20
+ const createDelayed = () => {
21
+ if (changeDelay != null && changeDelay >= 1) {
22
+ const changeHandler = onChangeDelay !== null && onChangeDelay !== void 0 ? onChangeDelay : onChange;
23
+ if (changeHandler)
24
+ return useDelayedExecutor(changeHandler, changeDelay);
25
+ }
26
+ return undefined;
27
+ };
28
+ const delayed = createDelayed();
23
29
  const onChangeEx = (event) => {
24
- if (onChange == null)
25
- return;
26
- if (changeDelay == null || changeDelay < 1) {
30
+ if (onChange && (delayed == null || onChangeDelay != null))
27
31
  onChange(event);
28
- return;
29
- }
30
32
  delayed === null || delayed === void 0 ? void 0 : delayed.call(undefined, event);
31
33
  };
32
34
  React.useEffect(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.1.46",
3
+ "version": "1.1.48",
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.70",
53
+ "@etsoo/appscript": "^1.3.76",
54
54
  "@etsoo/notificationbase": "^1.1.24",
55
- "@etsoo/react": "^1.6.49",
56
- "@etsoo/shared": "^1.1.89",
57
- "@mui/icons-material": "^5.11.9",
58
- "@mui/material": "^5.11.10",
59
- "@mui/x-data-grid": "^6.0.0-beta.5",
55
+ "@etsoo/react": "^1.6.51",
56
+ "@etsoo/shared": "^1.1.90",
57
+ "@mui/icons-material": "^5.11.11",
58
+ "@mui/material": "^5.11.13",
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,12 +71,12 @@
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.1",
74
+ "react-router-dom": "^6.9.0",
75
75
  "react-window": "^1.8.8"
76
76
  },
77
77
  "devDependencies": {
78
78
  "@babel/cli": "^7.21.0",
79
- "@babel/core": "^7.21.0",
79
+ "@babel/core": "^7.21.3",
80
80
  "@babel/plugin-transform-runtime": "^7.21.0",
81
81
  "@babel/preset-env": "^7.20.2",
82
82
  "@babel/preset-react": "^7.18.6",
@@ -84,11 +84,11 @@
84
84
  "@babel/runtime-corejs3": "^7.21.0",
85
85
  "@testing-library/jest-dom": "^5.16.5",
86
86
  "@testing-library/react": "^14.0.0",
87
- "@types/jest": "^29.4.0",
88
- "@typescript-eslint/eslint-plugin": "^5.53.0",
89
- "@typescript-eslint/parser": "^5.53.0",
90
- "jest": "^29.4.3",
91
- "jest-environment-jsdom": "^29.4.3",
87
+ "@types/jest": "^29.4.1",
88
+ "@typescript-eslint/eslint-plugin": "^5.55.0",
89
+ "@typescript-eslint/parser": "^5.55.0",
90
+ "jest": "^29.5.0",
91
+ "jest-environment-jsdom": "^29.5.0",
92
92
  "typescript": "^4.9.5"
93
93
  }
94
94
  }
@@ -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
  */
@@ -68,6 +74,13 @@ export type AddressSelectorProps = {
68
74
  */
69
75
  error?: boolean;
70
76
 
77
+ /**
78
+ * Get favored ids
79
+ * @param field Field
80
+ * @returns Result
81
+ */
82
+ favoredIds?: <F extends AddressField>(field: F) => AddressFavorType<F>[];
83
+
71
84
  /**
72
85
  * The helper text content.
73
86
  */
@@ -141,6 +154,7 @@ export function AddressSelector(props: AddressSelectorProps) {
141
154
  district,
142
155
  districtLabel = districtDefault,
143
156
  error,
157
+ favoredIds,
144
158
  helperText,
145
159
  hideRegion,
146
160
  label,
@@ -180,26 +194,41 @@ export function AddressSelector(props: AddressSelectorProps) {
180
194
  React.useEffect(() => {
181
195
  if (regionState == null) setStates([]);
182
196
  else
183
- api.states(regionState).then((items) => {
184
- if (items == null || !isMounted.current) return;
185
- setStates(items);
186
- });
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
+ });
187
206
  }, [regionState]);
188
207
  React.useEffect(() => {
189
208
  if (stateState == null) setCities([]);
190
209
  else
191
- api.cities(stateState).then((items) => {
192
- if (items == null || !isMounted.current) return;
193
- setCities(items);
194
- });
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
+ });
195
219
  }, [stateState]);
196
220
  React.useEffect(() => {
197
221
  if (cityState == null) setDistricts([]);
198
222
  else
199
- api.districts(cityState).then((items) => {
200
- if (items == null || !isMounted.current) return;
201
- setDistricts(items);
202
- });
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
+ });
203
232
  }, [cityState]);
204
233
 
205
234
  // Handle field change
@@ -275,7 +304,15 @@ export function AddressSelector(props: AddressSelectorProps) {
275
304
  fullWidth
276
305
  idValue={regionState}
277
306
  loadData={(keyword, id, items) =>
278
- api.getRegions({ keyword, id, items })
307
+ api.getRegions({
308
+ keyword,
309
+ id,
310
+ items,
311
+ favoredIds:
312
+ favoredIds == null
313
+ ? undefined
314
+ : favoredIds(AddressField.Region)
315
+ })
279
316
  }
280
317
  inputRequired={required}
281
318
  inputError={error}
@@ -294,7 +331,7 @@ export function AddressSelector(props: AddressSelectorProps) {
294
331
  fullWidth
295
332
  idValue={stateState}
296
333
  options={states}
297
- inputRequired={hideRegion ? required : undefined}
334
+ inputRequired={required}
298
335
  inputError={hideRegion ? error : undefined}
299
336
  inputHelperText={hideRegion ? helperText : undefined}
300
337
  onChange={(_event, value) =>
@@ -1,21 +1,28 @@
1
- import { useDelayedExecutor } from '@etsoo/react';
2
- import { TextField, TextFieldProps } from '@mui/material';
3
- import React from 'react';
4
- import { MUGlobal } from './MUGlobal';
1
+ import { useDelayedExecutor } from "@etsoo/react";
2
+ import { TextField, TextFieldProps } from "@mui/material";
3
+ import React from "react";
4
+ import { MUGlobal } from "./MUGlobal";
5
5
 
6
6
  /**
7
7
  * Input field props
8
8
  */
9
9
  export type InputFieldProps = TextFieldProps & {
10
- /**
11
- * Change delay (ms) to avoid repeatly dispatch onChange
12
- */
13
- changeDelay?: number;
10
+ /**
11
+ * Change delay (ms) to avoid repeatly dispatch onChange
12
+ */
13
+ changeDelay?: number;
14
14
 
15
- /**
16
- * Is the field read only?
17
- */
18
- readOnly?: boolean;
15
+ /**
16
+ * Change delay handler, without it onChange will be applied
17
+ */
18
+ onChangeDelay?: React.ChangeEventHandler<
19
+ HTMLTextAreaElement | HTMLInputElement
20
+ >;
21
+
22
+ /**
23
+ * Is the field read only?
24
+ */
25
+ readOnly?: boolean;
19
26
  };
20
27
 
21
28
  /**
@@ -24,62 +31,63 @@ export type InputFieldProps = TextFieldProps & {
24
31
  * @returns Component
25
32
  */
26
33
  export const InputField = React.forwardRef<HTMLDivElement, InputFieldProps>(
27
- (props, ref) => {
28
- // Destruct
29
- const {
30
- changeDelay,
31
- InputLabelProps = {},
32
- InputProps = {},
33
- onChange,
34
- readOnly,
35
- size = MUGlobal.inputFieldSize,
36
- variant = MUGlobal.inputFieldVariant,
37
- ...rest
38
- } = props;
39
-
40
- // Shrink
41
- InputLabelProps.shrink ??= MUGlobal.searchFieldShrink;
42
-
43
- // Read only
44
- if (readOnly != null) InputProps.readOnly = readOnly;
34
+ (props, ref) => {
35
+ // Destruct
36
+ const {
37
+ changeDelay,
38
+ InputLabelProps = {},
39
+ InputProps = {},
40
+ onChange,
41
+ onChangeDelay,
42
+ readOnly,
43
+ size = MUGlobal.inputFieldSize,
44
+ variant = MUGlobal.inputFieldVariant,
45
+ ...rest
46
+ } = props;
45
47
 
46
- const isMounted = React.useRef(true);
47
- const delayed =
48
- onChange != null && changeDelay != null && changeDelay >= 1
49
- ? useDelayedExecutor(onChange, changeDelay)
50
- : undefined;
48
+ // Shrink
49
+ InputLabelProps.shrink ??= MUGlobal.searchFieldShrink;
51
50
 
52
- const onChangeEx = (
53
- event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
54
- ) => {
55
- if (onChange == null) return;
51
+ // Read only
52
+ if (readOnly != null) InputProps.readOnly = readOnly;
56
53
 
57
- if (changeDelay == null || changeDelay < 1) {
58
- onChange(event);
59
- return;
60
- }
54
+ const isMounted = React.useRef(true);
55
+ const createDelayed = () => {
56
+ if (changeDelay != null && changeDelay >= 1) {
57
+ const changeHandler = onChangeDelay ?? onChange;
58
+ if (changeHandler)
59
+ return useDelayedExecutor(changeHandler, changeDelay);
60
+ }
61
+ return undefined;
62
+ };
63
+ const delayed = createDelayed();
61
64
 
62
- delayed?.call(undefined, event);
63
- };
65
+ const onChangeEx = (
66
+ event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
67
+ ) => {
68
+ if (onChange && (delayed == null || onChangeDelay != null))
69
+ onChange(event);
70
+ delayed?.call(undefined, event);
71
+ };
64
72
 
65
- React.useEffect(() => {
66
- return () => {
67
- isMounted.current = false;
68
- delayed?.clear();
69
- };
70
- }, []);
73
+ React.useEffect(() => {
74
+ return () => {
75
+ isMounted.current = false;
76
+ delayed?.clear();
77
+ };
78
+ }, []);
71
79
 
72
- // Layout
73
- return (
74
- <TextField
75
- ref={ref}
76
- InputLabelProps={InputLabelProps}
77
- InputProps={InputProps}
78
- onChange={onChangeEx}
79
- size={size}
80
- variant={variant}
81
- {...rest}
82
- />
83
- );
84
- }
80
+ // Layout
81
+ return (
82
+ <TextField
83
+ ref={ref}
84
+ InputLabelProps={InputLabelProps}
85
+ InputProps={InputProps}
86
+ onChange={onChangeEx}
87
+ size={size}
88
+ variant={variant}
89
+ {...rest}
90
+ />
91
+ );
92
+ }
85
93
  );