@etsoo/materialui 1.0.4 → 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.
@@ -0,0 +1,62 @@
1
+ import { DataTypes, IdDefaultType, LabelDefaultType } from '@etsoo/shared';
2
+ import { SelectChangeEvent } from '@mui/material';
3
+ import React from 'react';
4
+ /**
5
+ * Hierarchy selector props
6
+ */
7
+ export declare type HiSelectorProps<T extends object, D extends DataTypes.Keys<T> = IdDefaultType<T>, L extends DataTypes.Keys<T, string> = LabelDefaultType<T>> = {
8
+ /**
9
+ * Id field
10
+ */
11
+ idField?: D;
12
+ /**
13
+ * Error
14
+ */
15
+ error?: boolean;
16
+ /**
17
+ * The helper text content.
18
+ */
19
+ helperText?: React.ReactNode;
20
+ /**
21
+ * Name, also hidden input field name
22
+ */
23
+ name: string;
24
+ /**
25
+ * Label
26
+ */
27
+ label?: string;
28
+ /**
29
+ * Label field
30
+ */
31
+ labelField?: L;
32
+ /**
33
+ * Load data callback
34
+ */
35
+ loadData: (parent?: T[D]) => PromiseLike<T[] | null | undefined>;
36
+ /**
37
+ * On value change event
38
+ */
39
+ onChange?: (value: unknown) => void;
40
+ /**
41
+ * On select change event
42
+ */
43
+ onSelectChange?: (e: SelectChangeEvent<unknown>) => void;
44
+ /**
45
+ * Item change callback
46
+ */
47
+ onItemChange?: (option?: T) => void;
48
+ /**
49
+ * Required
50
+ */
51
+ required?: boolean;
52
+ /**
53
+ * Values
54
+ */
55
+ values?: T[D][];
56
+ };
57
+ /**
58
+ * Hierarchy selector
59
+ * @param props Prop
60
+ * @returns Component
61
+ */
62
+ export declare function HiSelector<T extends object, D extends DataTypes.Keys<T> = IdDefaultType<T>, L extends DataTypes.Keys<T, string> = LabelDefaultType<T>>(props: HiSelectorProps<T, D, L>): JSX.Element;
@@ -0,0 +1,55 @@
1
+ import { FormLabel, Grid } from '@mui/material';
2
+ import React from 'react';
3
+ import { SelectEx } from './SelectEx';
4
+ /**
5
+ * Hierarchy selector
6
+ * @param props Prop
7
+ * @returns Component
8
+ */
9
+ export function HiSelector(props) {
10
+ // Destruct
11
+ const { idField = 'id', error, helperText, name, label = name, labelField = 'name', loadData, onChange, onSelectChange, onItemChange, required, values = [] } = props;
12
+ const [localValues, setValues] = React.useState(values);
13
+ const updateValue = (value) => {
14
+ if (onChange)
15
+ onChange(value);
16
+ };
17
+ const doChange = (event, index) => {
18
+ const value = event.target.value;
19
+ const itemValue = value === '' ? undefined : value;
20
+ updateValue(itemValue);
21
+ const newValues = [...localValues.slice(0, index)];
22
+ if (itemValue != null)
23
+ newValues.push(itemValue);
24
+ setValues(newValues);
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);
35
+ };
36
+ React.useEffect(() => {
37
+ if (values.length > 0) {
38
+ setValues(values);
39
+ updateValue(values.at(-1));
40
+ }
41
+ }, [values]);
42
+ const currentValue = localValues.at(-1);
43
+ return (React.createElement(React.Fragment, null,
44
+ React.createElement(Grid, { item: true, xs: 12 },
45
+ React.createElement(FormLabel, { required: required, sx: { fontSize: (theme) => theme.typography.caption } }, label),
46
+ React.createElement("input", { type: "hidden", name: name, value: `${currentValue !== null && currentValue !== void 0 ? currentValue : ''}` })),
47
+ React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
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 })),
49
+ localValues[0] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
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 }))),
51
+ localValues[1] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 3 },
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 }))),
53
+ localValues[2] != null && (React.createElement(Grid, { item: true, xs: 6, md: 4, lg: 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 })))));
55
+ }
package/lib/SelectEx.d.ts CHANGED
@@ -9,6 +9,14 @@ export declare type SelectExProps<T extends object, D extends DataTypes.Keys<T>
9
9
  * Auto add blank item
10
10
  */
11
11
  autoAddBlankItem?: boolean;
12
+ /**
13
+ * The helper text content.
14
+ */
15
+ helperText?: React.ReactNode;
16
+ /**
17
+ * Input required
18
+ */
19
+ inputRequired?: boolean;
12
20
  /**
13
21
  * Id field
14
22
  */
@@ -29,6 +37,10 @@ export declare type SelectExProps<T extends object, D extends DataTypes.Keys<T>
29
37
  * Load data callback
30
38
  */
31
39
  loadData?: () => PromiseLike<T[] | null | undefined>;
40
+ /**
41
+ * Item change callback
42
+ */
43
+ onItemChange?: (option: T | undefined, userAction: boolean) => void;
32
44
  /**
33
45
  * Item click handler
34
46
  */
package/lib/SelectEx.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Checkbox, FormControl, InputLabel, ListItemText, MenuItem, OutlinedInput, Select } from '@mui/material';
1
+ import { Checkbox, FormControl, FormHelperText, InputLabel, ListItemText, MenuItem, OutlinedInput, Select } from '@mui/material';
2
2
  import React from 'react';
3
3
  import { MUGlobal } from './MUGlobal';
4
4
  import { ListItemRightIcon } from './ListItemRightIcon';
@@ -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', 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]);
@@ -112,15 +125,16 @@ export function SelectEx(props) {
112
125
  };
113
126
  }, []);
114
127
  // Layout
115
- return (React.createElement(FormControl, { size: search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize, fullWidth: fullWidth },
128
+ return (React.createElement(FormControl, { size: search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize, fullWidth: fullWidth, error: error },
116
129
  React.createElement(InputLabel, { id: labelId, shrink: search
117
130
  ? MUGlobal.searchFieldShrink
118
131
  : MUGlobal.inputFieldShrink }, label),
119
132
  React.createElement(Select, { ref: divRef, value: localOptions.some((option) => itemChecked(getId(option)))
120
133
  ? valueState !== null && valueState !== void 0 ? valueState : ''
121
- : '', input: React.createElement(OutlinedInput, { notched: true, label: label }), labelId: labelId, name: name, multiple: multiple, onChange: (event, child) => {
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) => {
@@ -154,5 +168,6 @@ export function SelectEx(props) {
154
168
  multiple && React.createElement(Checkbox, { checked: itemChecked(id) }),
155
169
  React.createElement(ListItemText, { primary: label }),
156
170
  itemIconRenderer && (React.createElement(ListItemRightIcon, null, itemIconRenderer(option[idField])))));
157
- }))));
171
+ })),
172
+ helperText != null && (React.createElement(FormHelperText, null, helperText))));
158
173
  }
package/lib/index.d.ts CHANGED
@@ -38,6 +38,7 @@ export * from './EmailInput';
38
38
  export * from './FabBox';
39
39
  export * from './FlexBox';
40
40
  export * from './GridDataFormat';
41
+ export * from './HiSelector';
41
42
  export * from './IconButtonLink';
42
43
  export * from './InputField';
43
44
  export * from './ItemList';
package/lib/index.js CHANGED
@@ -38,6 +38,7 @@ export * from './EmailInput';
38
38
  export * from './FabBox';
39
39
  export * from './FlexBox';
40
40
  export * from './GridDataFormat';
41
+ export * from './HiSelector';
41
42
  export * from './IconButtonLink';
42
43
  export * from './InputField';
43
44
  export * from './ItemList';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.0.4",
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",
@@ -0,0 +1,221 @@
1
+ import { DataTypes, IdDefaultType, LabelDefaultType } from '@etsoo/shared';
2
+ import { FormLabel, Grid, SelectChangeEvent } from '@mui/material';
3
+ import React from 'react';
4
+ import { SelectEx } from './SelectEx';
5
+
6
+ /**
7
+ * Hierarchy selector props
8
+ */
9
+ export type HiSelectorProps<
10
+ T extends object,
11
+ D extends DataTypes.Keys<T> = IdDefaultType<T>,
12
+ L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
13
+ > = {
14
+ /**
15
+ * Id field
16
+ */
17
+ idField?: D;
18
+
19
+ /**
20
+ * Error
21
+ */
22
+ error?: boolean;
23
+
24
+ /**
25
+ * The helper text content.
26
+ */
27
+ helperText?: React.ReactNode;
28
+
29
+ /**
30
+ * Name, also hidden input field name
31
+ */
32
+ name: string;
33
+
34
+ /**
35
+ * Label
36
+ */
37
+ label?: string;
38
+
39
+ /**
40
+ * Label field
41
+ */
42
+ labelField?: L;
43
+
44
+ /**
45
+ * Load data callback
46
+ */
47
+ loadData: (parent?: T[D]) => PromiseLike<T[] | null | undefined>;
48
+
49
+ /**
50
+ * On value change event
51
+ */
52
+ onChange?: (value: unknown) => void;
53
+
54
+ /**
55
+ * On select change event
56
+ */
57
+ onSelectChange?: (e: SelectChangeEvent<unknown>) => void;
58
+
59
+ /**
60
+ * Item change callback
61
+ */
62
+ onItemChange?: (option?: T) => void;
63
+
64
+ /**
65
+ * Required
66
+ */
67
+ required?: boolean;
68
+
69
+ /**
70
+ * Values
71
+ */
72
+ values?: T[D][];
73
+ };
74
+
75
+ /**
76
+ * Hierarchy selector
77
+ * @param props Prop
78
+ * @returns Component
79
+ */
80
+ export function HiSelector<
81
+ T extends object,
82
+ D extends DataTypes.Keys<T> = IdDefaultType<T>,
83
+ L extends DataTypes.Keys<T, string> = LabelDefaultType<T>
84
+ >(props: HiSelectorProps<T, D, L>) {
85
+ // Destruct
86
+ const {
87
+ idField = 'id' as D,
88
+ error,
89
+ helperText,
90
+ name,
91
+ label = name,
92
+ labelField = 'name' as L,
93
+ loadData,
94
+ onChange,
95
+ onSelectChange,
96
+ onItemChange,
97
+ required,
98
+ values = []
99
+ } = props;
100
+
101
+ // Value type
102
+ type ValueType = T[D];
103
+ const [localValues, setValues] = React.useState<ValueType[]>(values);
104
+
105
+ const updateValue = (value?: T[D]) => {
106
+ if (onChange) onChange(value);
107
+ };
108
+
109
+ const doChange = (event: SelectChangeEvent<unknown>, index: number) => {
110
+ const value = event.target.value;
111
+ const itemValue = value === '' ? undefined : (value as T[D]);
112
+ updateValue(itemValue);
113
+
114
+ const newValues = [...localValues.slice(0, index)];
115
+ if (itemValue != null) newValues.push(itemValue);
116
+ setValues(newValues);
117
+
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);
129
+ };
130
+
131
+ React.useEffect(() => {
132
+ if (values.length > 0) {
133
+ setValues(values);
134
+ updateValue(values.at(-1));
135
+ }
136
+ }, [values]);
137
+
138
+ const currentValue = localValues.at(-1);
139
+
140
+ return (
141
+ <React.Fragment>
142
+ <Grid item xs={12}>
143
+ <FormLabel
144
+ required={required}
145
+ sx={{ fontSize: (theme) => theme.typography.caption }}
146
+ >
147
+ {label}
148
+ </FormLabel>
149
+ <input
150
+ type="hidden"
151
+ name={name}
152
+ value={`${currentValue ?? ''}`}
153
+ />
154
+ </Grid>
155
+ <Grid item xs={6} md={4} lg={3}>
156
+ <SelectEx<T, D, L>
157
+ idField={idField}
158
+ labelField={labelField}
159
+ name="tab1"
160
+ search
161
+ fullWidth
162
+ loadData={() => loadData()}
163
+ value={values[0]}
164
+ onChange={(event) => doChange(event, 0)}
165
+ onItemChange={doItemChange}
166
+ inputRequired={required}
167
+ error={error}
168
+ helperText={helperText}
169
+ />
170
+ </Grid>
171
+ {localValues[0] != null && (
172
+ <Grid item xs={6} md={4} lg={3}>
173
+ <SelectEx<T, D, L>
174
+ key={`${localValues[0]}`}
175
+ idField={idField}
176
+ labelField={labelField}
177
+ name="tab2"
178
+ search
179
+ fullWidth
180
+ loadData={() => loadData(localValues[0])}
181
+ value={values[1]}
182
+ onChange={(event) => doChange(event, 1)}
183
+ onItemChange={doItemChange}
184
+ />
185
+ </Grid>
186
+ )}
187
+ {localValues[1] != null && (
188
+ <Grid item xs={6} md={4} lg={3}>
189
+ <SelectEx<T, D, L>
190
+ key={`${localValues[1]}`}
191
+ idField={idField}
192
+ labelField={labelField}
193
+ name="tab3"
194
+ search
195
+ fullWidth
196
+ loadData={() => loadData(localValues[1])}
197
+ value={values[2]}
198
+ onChange={(event) => doChange(event, 2)}
199
+ onItemChange={doItemChange}
200
+ />
201
+ </Grid>
202
+ )}
203
+ {localValues[2] != null && (
204
+ <Grid item xs={6} md={4} lg={3}>
205
+ <SelectEx<T, D, L>
206
+ key={`${localValues[2]}`}
207
+ idField={idField}
208
+ labelField={labelField}
209
+ name="tab4"
210
+ search
211
+ fullWidth
212
+ loadData={() => loadData(localValues[2])}
213
+ value={values[3]}
214
+ onChange={(event) => doChange(event, 3)}
215
+ onItemChange={doItemChange}
216
+ />
217
+ </Grid>
218
+ )}
219
+ </React.Fragment>
220
+ );
221
+ }
package/src/SelectEx.tsx CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  Checkbox,
3
3
  FormControl,
4
+ FormHelperText,
4
5
  InputLabel,
5
6
  ListItemText,
6
7
  MenuItem,
@@ -34,6 +35,16 @@ export type SelectExProps<
34
35
  */
35
36
  autoAddBlankItem?: boolean;
36
37
 
38
+ /**
39
+ * The helper text content.
40
+ */
41
+ helperText?: React.ReactNode;
42
+
43
+ /**
44
+ * Input required
45
+ */
46
+ inputRequired?: boolean;
47
+
37
48
  /**
38
49
  * Id field
39
50
  */
@@ -59,6 +70,11 @@ export type SelectExProps<
59
70
  */
60
71
  loadData?: () => PromiseLike<T[] | null | undefined>;
61
72
 
73
+ /**
74
+ * Item change callback
75
+ */
76
+ onItemChange?: (option: T | undefined, userAction: boolean) => void;
77
+
62
78
  /**
63
79
  * Item click handler
64
80
  */
@@ -94,11 +110,15 @@ export function SelectEx<
94
110
  const {
95
111
  defaultValue,
96
112
  idField = 'id' as D,
113
+ error,
114
+ helperText,
115
+ inputRequired,
97
116
  itemIconRenderer,
98
117
  itemStyle,
99
118
  label,
100
119
  labelField = 'label' as L,
101
120
  loadData,
121
+ onItemChange,
102
122
  onItemClick,
103
123
  onLoadData,
104
124
  multiple = false,
@@ -116,11 +136,28 @@ export function SelectEx<
116
136
  const [localOptions, setOptions] = React.useState(options);
117
137
  const isMounted = React.useRef(true);
118
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
+
119
156
  // When options change
120
157
  // [options] will cause infinite loop
121
158
  const propertyWay = loadData == null;
122
159
  React.useEffect(() => {
123
- if (propertyWay && options != null) setOptions(options);
160
+ if (propertyWay && options != null) setOptionsAdd(options);
124
161
  }, [JSON.stringify(options), propertyWay]);
125
162
 
126
163
  // Local value
@@ -193,7 +230,7 @@ export function SelectEx<
193
230
  if (autoAddBlankItem) {
194
231
  Utils.addBlankItem(result, idField, labelField);
195
232
  }
196
- setOptions(result);
233
+ setOptionsAdd(result);
197
234
  });
198
235
  }
199
236
  }, [localValue]);
@@ -218,6 +255,7 @@ export function SelectEx<
218
255
  <FormControl
219
256
  size={search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize}
220
257
  fullWidth={fullWidth}
258
+ error={error}
221
259
  >
222
260
  <InputLabel
223
261
  id={labelId}
@@ -236,12 +274,19 @@ export function SelectEx<
236
274
  ? valueState ?? ''
237
275
  : ''
238
276
  }
239
- input={<OutlinedInput notched label={label} />}
277
+ input={
278
+ <OutlinedInput
279
+ notched
280
+ label={label}
281
+ required={inputRequired}
282
+ />
283
+ }
240
284
  labelId={labelId}
241
285
  name={name}
242
286
  multiple={multiple}
243
287
  onChange={(event, child) => {
244
288
  if (onChange) onChange(event, child);
289
+ doItemChange(localOptions, event.target.value, true);
245
290
  if (multiple) handleChange(event);
246
291
  }}
247
292
  renderValue={(selected) => {
@@ -296,6 +341,9 @@ export function SelectEx<
296
341
  );
297
342
  })}
298
343
  </Select>
344
+ {helperText != null && (
345
+ <FormHelperText>{helperText}</FormHelperText>
346
+ )}
299
347
  </FormControl>
300
348
  );
301
349
  }
package/src/index.ts CHANGED
@@ -41,6 +41,7 @@ export * from './EmailInput';
41
41
  export * from './FabBox';
42
42
  export * from './FlexBox';
43
43
  export * from './GridDataFormat';
44
+ export * from './HiSelector';
44
45
  export * from './IconButtonLink';
45
46
  export * from './InputField';
46
47
  export * from './ItemList';