@etsoo/materialui 1.0.6 → 1.0.7

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.
@@ -38,9 +38,13 @@ export declare type HiSelectorProps<T extends object, D extends DataTypes.Keys<T
38
38
  */
39
39
  onChange?: (value: unknown) => void;
40
40
  /**
41
- * On item change event
41
+ * On select change event
42
42
  */
43
- onItemChange?: (e: SelectChangeEvent<unknown>) => void;
43
+ onSelectChange?: (e: SelectChangeEvent<unknown>) => void;
44
+ /**
45
+ * Item change callback
46
+ */
47
+ onItemChange?: (option?: T) => void;
44
48
  /**
45
49
  * Required
46
50
  */
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 = name, labelField = 'name', loadData, onChange, onItemChange, required, values = [] } = props;
11
+ const { idField = 'id', error, helperText, name, label = name, labelField = 'name', loadData, onChange, onSelectChange, onItemChange, required, values = [] } = props;
12
12
  const [localValues, setValues] = React.useState(values);
13
13
  const updateValue = (value) => {
14
14
  if (onChange)
@@ -22,8 +22,16 @@ export function HiSelector(props) {
22
22
  if (itemValue != null)
23
23
  newValues.push(itemValue);
24
24
  setValues(newValues);
25
- if (onItemChange)
26
- onItemChange(event);
25
+ if (onSelectChange)
26
+ onSelectChange(event);
27
+ };
28
+ const doItemChange = (option, userAction) => {
29
+ if (onItemChange == null)
30
+ return;
31
+ if (!userAction &&
32
+ (option == null || option[idField] !== values.at(-1)))
33
+ return;
34
+ onItemChange(option);
27
35
  };
28
36
  React.useEffect(() => {
29
37
  if (values.length > 0) {
@@ -37,11 +45,11 @@ export function HiSelector(props) {
37
45
  React.createElement(FormLabel, { required: required, sx: { fontSize: (theme) => theme.typography.caption } }, label),
38
46
  React.createElement("input", { type: "hidden", name: name, value: `${currentValue !== null && currentValue !== void 0 ? currentValue : ''}` })),
39
47
  React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
40
- React.createElement(SelectEx, { idField: idField, labelField: labelField, name: "tab1", search: true, fullWidth: true, loadData: () => loadData(), value: values[0], onChange: (event) => doChange(event, 0), inputRequired: required, error: error, helperText: helperText })),
48
+ React.createElement(SelectEx, { idField: idField, labelField: labelField, name: "tab1", search: true, fullWidth: true, loadData: () => loadData(), value: values[0], onChange: (event) => doChange(event, 0), onItemChange: doItemChange, inputRequired: required, error: error, helperText: helperText })),
41
49
  localValues[0] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
42
- React.createElement(SelectEx, { key: `${localValues[0]}`, idField: idField, labelField: labelField, name: "tab2", search: true, fullWidth: true, loadData: () => loadData(localValues[0]), value: values[1], onChange: (event) => doChange(event, 1) }))),
50
+ React.createElement(SelectEx, { key: `${localValues[0]}`, idField: idField, labelField: labelField, name: "tab2", search: true, fullWidth: true, loadData: () => loadData(localValues[0]), value: values[1], onChange: (event) => doChange(event, 1), onItemChange: doItemChange }))),
43
51
  localValues[1] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
44
- React.createElement(SelectEx, { key: `${localValues[1]}`, idField: idField, labelField: labelField, name: "tab3", search: true, fullWidth: true, loadData: () => loadData(localValues[1]), value: values[2], onChange: (event) => doChange(event, 2) }))),
52
+ React.createElement(SelectEx, { key: `${localValues[1]}`, idField: idField, labelField: labelField, name: "tab3", search: true, fullWidth: true, loadData: () => loadData(localValues[1]), value: values[2], onChange: (event) => doChange(event, 2), onItemChange: doItemChange }))),
45
53
  localValues[2] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
46
- React.createElement(SelectEx, { key: `${localValues[2]}`, idField: idField, labelField: labelField, name: "tab4", search: true, fullWidth: true, loadData: () => loadData(localValues[2]), value: values[3], onChange: (event) => doChange(event, 3) })))));
54
+ React.createElement(SelectEx, { key: `${localValues[2]}`, idField: idField, labelField: labelField, name: "tab4", search: true, fullWidth: true, loadData: () => loadData(localValues[2]), value: values[3], onChange: (event) => doChange(event, 3), onItemChange: doItemChange })))));
47
55
  }
package/lib/SelectEx.d.ts CHANGED
@@ -37,6 +37,10 @@ export declare type SelectExProps<T extends object, D extends DataTypes.Keys<T>
37
37
  * Load data callback
38
38
  */
39
39
  loadData?: () => PromiseLike<T[] | null | undefined>;
40
+ /**
41
+ * Item change callback
42
+ */
43
+ onItemChange?: (option: T | undefined, userAction: boolean) => void;
40
44
  /**
41
45
  * Item click handler
42
46
  */
package/lib/SelectEx.js CHANGED
@@ -12,16 +12,29 @@ import { ReactUtils } from '@etsoo/react';
12
12
  export function SelectEx(props) {
13
13
  var _a;
14
14
  // Destruct
15
- const { defaultValue, idField = 'id', error, helperText, inputRequired, itemIconRenderer, itemStyle, label, labelField = 'label', loadData, onItemClick, onLoadData, multiple = false, name, options = [], search = false, autoAddBlankItem = search, value, onChange, fullWidth, ...rest } = props;
15
+ const { defaultValue, idField = 'id', error, helperText, inputRequired, itemIconRenderer, itemStyle, label, labelField = 'label', loadData, onItemChange, onItemClick, onLoadData, multiple = false, name, options = [], search = false, autoAddBlankItem = search, value, onChange, fullWidth, ...rest } = props;
16
16
  // Options state
17
17
  const [localOptions, setOptions] = React.useState(options);
18
18
  const isMounted = React.useRef(true);
19
+ const doItemChange = (options, value, userAction) => {
20
+ if (onItemChange == null)
21
+ return;
22
+ if (value == null || value === '')
23
+ onItemChange(undefined, userAction);
24
+ const option = options.find((option) => option[idField] === value);
25
+ onItemChange(option, userAction);
26
+ };
27
+ const setOptionsAdd = (options) => {
28
+ setOptions(options);
29
+ if (valueState != null && valueState !== '')
30
+ doItemChange(options, valueState, false);
31
+ };
19
32
  // When options change
20
33
  // [options] will cause infinite loop
21
34
  const propertyWay = loadData == null;
22
35
  React.useEffect(() => {
23
36
  if (propertyWay && options != null)
24
- setOptions(options);
37
+ setOptionsAdd(options);
25
38
  }, [JSON.stringify(options), propertyWay]);
26
39
  // Local value
27
40
  const valueSource = (_a = defaultValue !== null && defaultValue !== void 0 ? defaultValue : value) !== null && _a !== void 0 ? _a : '';
@@ -92,7 +105,7 @@ export function SelectEx(props) {
92
105
  if (autoAddBlankItem) {
93
106
  Utils.addBlankItem(result, idField, labelField);
94
107
  }
95
- setOptions(result);
108
+ setOptionsAdd(result);
96
109
  });
97
110
  }
98
111
  }, [localValue]);
@@ -121,6 +134,7 @@ export function SelectEx(props) {
121
134
  : '', input: React.createElement(OutlinedInput, { notched: true, label: label, required: inputRequired }), labelId: labelId, name: name, multiple: multiple, onChange: (event, child) => {
122
135
  if (onChange)
123
136
  onChange(event, child);
137
+ doItemChange(localOptions, event.target.value, true);
124
138
  if (multiple)
125
139
  handleChange(event);
126
140
  }, renderValue: (selected) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -51,12 +51,12 @@
51
51
  "@emotion/css": "^11.10.0",
52
52
  "@emotion/react": "^11.10.4",
53
53
  "@emotion/styled": "^11.10.4",
54
- "@etsoo/appscript": "^1.2.88",
54
+ "@etsoo/appscript": "^1.2.89",
55
55
  "@etsoo/notificationbase": "^1.1.7",
56
- "@etsoo/react": "^1.5.86",
57
- "@etsoo/shared": "^1.1.51",
56
+ "@etsoo/react": "^1.5.87",
57
+ "@etsoo/shared": "^1.1.52",
58
58
  "@mui/icons-material": "^5.10.3",
59
- "@mui/material": "^5.10.3",
59
+ "@mui/material": "^5.10.4",
60
60
  "@types/pica": "^9.0.1",
61
61
  "@types/pulltorefreshjs": "^0.1.5",
62
62
  "@types/react": "^18.0.18",
@@ -76,19 +76,19 @@
76
76
  },
77
77
  "devDependencies": {
78
78
  "@babel/cli": "^7.18.10",
79
- "@babel/core": "^7.18.13",
79
+ "@babel/core": "^7.19.0",
80
80
  "@babel/plugin-transform-runtime": "^7.18.10",
81
- "@babel/preset-env": "^7.18.10",
82
- "@babel/runtime-corejs3": "^7.18.9",
81
+ "@babel/preset-env": "^7.19.0",
82
+ "@babel/runtime-corejs3": "^7.19.0",
83
83
  "@testing-library/jest-dom": "^5.16.5",
84
- "@testing-library/react": "^13.3.0",
84
+ "@testing-library/react": "^13.4.0",
85
85
  "@types/jest": "^29.0.0",
86
- "@typescript-eslint/eslint-plugin": "^5.36.1",
87
- "@typescript-eslint/parser": "^5.36.1",
86
+ "@typescript-eslint/eslint-plugin": "^5.36.2",
87
+ "@typescript-eslint/parser": "^5.36.2",
88
88
  "eslint": "^8.23.0",
89
89
  "eslint-config-airbnb-base": "^15.0.0",
90
90
  "eslint-plugin-import": "^2.26.0",
91
- "eslint-plugin-react": "^7.31.1",
91
+ "eslint-plugin-react": "^7.31.7",
92
92
  "jest": "^28.1.3",
93
93
  "jest-environment-jsdom": "^28.1.3",
94
94
  "ts-jest": "^28.0.8",
@@ -52,9 +52,14 @@ export type HiSelectorProps<
52
52
  onChange?: (value: unknown) => void;
53
53
 
54
54
  /**
55
- * On item change event
55
+ * On select change event
56
56
  */
57
- onItemChange?: (e: SelectChangeEvent<unknown>) => void;
57
+ onSelectChange?: (e: SelectChangeEvent<unknown>) => void;
58
+
59
+ /**
60
+ * Item change callback
61
+ */
62
+ onItemChange?: (option?: T) => void;
58
63
 
59
64
  /**
60
65
  * Required
@@ -87,6 +92,7 @@ export function HiSelector<
87
92
  labelField = 'name' as L,
88
93
  loadData,
89
94
  onChange,
95
+ onSelectChange,
90
96
  onItemChange,
91
97
  required,
92
98
  values = []
@@ -109,7 +115,17 @@ export function HiSelector<
109
115
  if (itemValue != null) newValues.push(itemValue);
110
116
  setValues(newValues);
111
117
 
112
- if (onItemChange) onItemChange(event);
118
+ if (onSelectChange) onSelectChange(event);
119
+ };
120
+
121
+ const doItemChange = (option: T | undefined, userAction: boolean) => {
122
+ if (onItemChange == null) return;
123
+ if (
124
+ !userAction &&
125
+ (option == null || option[idField] !== values.at(-1))
126
+ )
127
+ return;
128
+ onItemChange(option);
113
129
  };
114
130
 
115
131
  React.useEffect(() => {
@@ -146,6 +162,7 @@ export function HiSelector<
146
162
  loadData={() => loadData()}
147
163
  value={values[0]}
148
164
  onChange={(event) => doChange(event, 0)}
165
+ onItemChange={doItemChange}
149
166
  inputRequired={required}
150
167
  error={error}
151
168
  helperText={helperText}
@@ -163,6 +180,7 @@ export function HiSelector<
163
180
  loadData={() => loadData(localValues[0])}
164
181
  value={values[1]}
165
182
  onChange={(event) => doChange(event, 1)}
183
+ onItemChange={doItemChange}
166
184
  />
167
185
  </Grid>
168
186
  )}
@@ -178,6 +196,7 @@ export function HiSelector<
178
196
  loadData={() => loadData(localValues[1])}
179
197
  value={values[2]}
180
198
  onChange={(event) => doChange(event, 2)}
199
+ onItemChange={doItemChange}
181
200
  />
182
201
  </Grid>
183
202
  )}
@@ -193,6 +212,7 @@ export function HiSelector<
193
212
  loadData={() => loadData(localValues[2])}
194
213
  value={values[3]}
195
214
  onChange={(event) => doChange(event, 3)}
215
+ onItemChange={doItemChange}
196
216
  />
197
217
  </Grid>
198
218
  )}
package/src/SelectEx.tsx CHANGED
@@ -70,6 +70,11 @@ export type SelectExProps<
70
70
  */
71
71
  loadData?: () => PromiseLike<T[] | null | undefined>;
72
72
 
73
+ /**
74
+ * Item change callback
75
+ */
76
+ onItemChange?: (option: T | undefined, userAction: boolean) => void;
77
+
73
78
  /**
74
79
  * Item click handler
75
80
  */
@@ -113,6 +118,7 @@ export function SelectEx<
113
118
  label,
114
119
  labelField = 'label' as L,
115
120
  loadData,
121
+ onItemChange,
116
122
  onItemClick,
117
123
  onLoadData,
118
124
  multiple = false,
@@ -130,11 +136,28 @@ export function SelectEx<
130
136
  const [localOptions, setOptions] = React.useState(options);
131
137
  const isMounted = React.useRef(true);
132
138
 
139
+ const doItemChange = (
140
+ options: readonly T[],
141
+ value: unknown,
142
+ userAction: boolean
143
+ ) => {
144
+ if (onItemChange == null) return;
145
+ if (value == null || value === '') onItemChange(undefined, userAction);
146
+ const option = options.find((option) => option[idField] === value);
147
+ onItemChange(option, userAction);
148
+ };
149
+
150
+ const setOptionsAdd = (options: readonly T[]) => {
151
+ setOptions(options);
152
+ if (valueState != null && valueState !== '')
153
+ doItemChange(options, valueState, false);
154
+ };
155
+
133
156
  // When options change
134
157
  // [options] will cause infinite loop
135
158
  const propertyWay = loadData == null;
136
159
  React.useEffect(() => {
137
- if (propertyWay && options != null) setOptions(options);
160
+ if (propertyWay && options != null) setOptionsAdd(options);
138
161
  }, [JSON.stringify(options), propertyWay]);
139
162
 
140
163
  // Local value
@@ -207,7 +230,7 @@ export function SelectEx<
207
230
  if (autoAddBlankItem) {
208
231
  Utils.addBlankItem(result, idField, labelField);
209
232
  }
210
- setOptions(result);
233
+ setOptionsAdd(result);
211
234
  });
212
235
  }
213
236
  }, [localValue]);
@@ -263,6 +286,7 @@ export function SelectEx<
263
286
  multiple={multiple}
264
287
  onChange={(event, child) => {
265
288
  if (onChange) onChange(event, child);
289
+ doItemChange(localOptions, event.target.value, true);
266
290
  if (multiple) handleChange(event);
267
291
  }}
268
292
  renderValue={(selected) => {