@etsoo/materialui 1.0.27 → 1.0.29

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/SelectEx.d.ts CHANGED
@@ -45,10 +45,6 @@ export declare type SelectExProps<T extends object, D extends DataTypes.Keys<T>
45
45
  * Item click handler
46
46
  */
47
47
  onItemClick?: (event: React.MouseEvent, option: T) => void;
48
- /**
49
- * Item mouse down handler
50
- */
51
- onItemMouseDown?: (event: React.MouseEvent, option: T) => void;
52
48
  /**
53
49
  * On load data handler
54
50
  */
@@ -57,6 +53,10 @@ export declare type SelectExProps<T extends object, D extends DataTypes.Keys<T>
57
53
  * Array of options.
58
54
  */
59
55
  options?: ReadonlyArray<T>;
56
+ /**
57
+ * Supports refresh label or component
58
+ */
59
+ refresh?: string | React.ReactNode;
60
60
  /**
61
61
  * Is search case?
62
62
  */
package/lib/SelectEx.js CHANGED
@@ -1,7 +1,8 @@
1
- import { Checkbox, FormControl, FormHelperText, InputLabel, ListItemText, MenuItem, OutlinedInput, Select } from '@mui/material';
1
+ import { Checkbox, FormControl, FormHelperText, IconButton, InputLabel, ListItemText, MenuItem, OutlinedInput, Select, Stack } from '@mui/material';
2
2
  import React from 'react';
3
3
  import { MUGlobal } from './MUGlobal';
4
4
  import { ListItemRightIcon } from './ListItemRightIcon';
5
+ import RefreshIcon from '@mui/icons-material/Refresh';
5
6
  import { Utils } from '@etsoo/shared';
6
7
  /**
7
8
  * Extended select component
@@ -11,7 +12,7 @@ import { Utils } from '@etsoo/shared';
11
12
  export function SelectEx(props) {
12
13
  var _a;
13
14
  // Destruct
14
- const { defaultValue, idField = 'id', error, helperText, inputRequired, itemIconRenderer, itemStyle, label, labelField = 'label', loadData, onItemChange, onItemClick, onItemMouseDown, 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, refresh, search = false, autoAddBlankItem = search, value, onChange, fullWidth, ...rest } = props;
15
16
  // Options state
16
17
  const [localOptions, setOptions] = React.useState([]);
17
18
  const isMounted = React.useRef(true);
@@ -97,20 +98,24 @@ export function SelectEx(props) {
97
98
  };
98
99
  // Refs
99
100
  const divRef = React.useRef();
101
+ // Refresh list data
102
+ const refreshData = () => {
103
+ if (loadData == null)
104
+ return;
105
+ loadData().then((result) => {
106
+ if (result == null || !isMounted.current)
107
+ return;
108
+ if (onLoadData)
109
+ onLoadData(result);
110
+ if (autoAddBlankItem) {
111
+ Utils.addBlankItem(result, idField, labelField);
112
+ }
113
+ setOptionsAdd(result);
114
+ });
115
+ };
100
116
  // When value change
101
117
  React.useEffect(() => {
102
- if (loadData) {
103
- loadData().then((result) => {
104
- if (result == null || !isMounted.current)
105
- return;
106
- if (onLoadData)
107
- onLoadData(result);
108
- if (autoAddBlankItem) {
109
- Utils.addBlankItem(result, idField, labelField);
110
- }
111
- setOptionsAdd(result);
112
- });
113
- }
118
+ refreshData();
114
119
  }, [localValue]);
115
120
  // When layout ready
116
121
  React.useEffect(() => {
@@ -128,48 +133,53 @@ export function SelectEx(props) {
128
133
  };
129
134
  }, []);
130
135
  // Layout
131
- return (React.createElement(FormControl, { size: search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize, fullWidth: fullWidth, error: error },
132
- React.createElement(InputLabel, { id: labelId, shrink: search
133
- ? MUGlobal.searchFieldShrink
134
- : MUGlobal.inputFieldShrink }, label),
135
- React.createElement(Select, { ref: divRef, value: localOptions.some((option) => itemChecked(getId(option)))
136
- ? valueState !== null && valueState !== void 0 ? valueState : ''
137
- : '', input: React.createElement(OutlinedInput, { notched: true, label: label, required: inputRequired }), labelId: labelId, name: name, multiple: multiple, onChange: (event, child) => {
138
- if (onChange)
139
- onChange(event, child);
140
- doItemChange(localOptions, event.target.value, true);
141
- handleChange(event);
142
- }, renderValue: (selected) => {
143
- // The text shows up
144
- return localOptions
145
- .filter((option) => {
146
- const id = getId(option);
147
- return Array.isArray(selected)
148
- ? selected.indexOf(id) !== -1
149
- : selected === id;
150
- })
151
- .map((option) => getLabel(option))
152
- .join(', ');
153
- }, sx: { minWidth: '150px' }, fullWidth: fullWidth, ...rest }, localOptions.map((option) => {
154
- // Option id
155
- const id = getId(option);
156
- // Option label
157
- const label = getLabel(option);
158
- // Option
159
- return (React.createElement(MenuItem, { key: id, value: id, onClick: (event) => {
160
- if (onItemClick) {
161
- onItemClick(event, option);
162
- }
163
- }, onMouseDown: (event) => {
164
- if (onItemMouseDown) {
165
- onItemMouseDown(event, option);
136
+ return (React.createElement(Stack, { direction: "row" },
137
+ React.createElement(FormControl, { size: search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize, fullWidth: fullWidth, error: error },
138
+ React.createElement(InputLabel, { id: labelId, shrink: search
139
+ ? MUGlobal.searchFieldShrink
140
+ : MUGlobal.inputFieldShrink }, label),
141
+ React.createElement(Select, { ref: divRef, value: localOptions.some((option) => itemChecked(getId(option)))
142
+ ? valueState !== null && valueState !== void 0 ? valueState : ''
143
+ : '', input: React.createElement(OutlinedInput, { notched: true, label: label, required: inputRequired }), labelId: labelId, name: name, multiple: multiple, onChange: (event, child) => {
144
+ if (onChange) {
145
+ onChange(event, child);
146
+ // event.preventDefault() will block executing
147
+ if (event.defaultPrevented)
148
+ return;
166
149
  }
167
- }, style: itemStyle == null
168
- ? undefined
169
- : itemStyle(option) },
170
- multiple && React.createElement(Checkbox, { checked: itemChecked(id) }),
171
- React.createElement(ListItemText, { primary: label }),
172
- itemIconRenderer && (React.createElement(ListItemRightIcon, null, itemIconRenderer(option[idField])))));
173
- })),
174
- helperText != null && (React.createElement(FormHelperText, null, helperText))));
150
+ doItemChange(localOptions, event.target.value, true);
151
+ handleChange(event);
152
+ }, renderValue: (selected) => {
153
+ // The text shows up
154
+ return localOptions
155
+ .filter((option) => {
156
+ const id = getId(option);
157
+ return Array.isArray(selected)
158
+ ? selected.indexOf(id) !== -1
159
+ : selected === id;
160
+ })
161
+ .map((option) => getLabel(option))
162
+ .join(', ');
163
+ }, sx: { minWidth: '150px' }, fullWidth: fullWidth, ...rest }, localOptions.map((option) => {
164
+ // Option id
165
+ const id = getId(option);
166
+ // Option label
167
+ const label = getLabel(option);
168
+ // Option
169
+ return (React.createElement(MenuItem, { key: id, value: id, onClick: (event) => {
170
+ if (onItemClick) {
171
+ onItemClick(event, option);
172
+ }
173
+ }, style: itemStyle == null
174
+ ? undefined
175
+ : itemStyle(option) },
176
+ multiple && (React.createElement(Checkbox, { checked: itemChecked(id) })),
177
+ React.createElement(ListItemText, { primary: label }),
178
+ itemIconRenderer && (React.createElement(ListItemRightIcon, null, itemIconRenderer(option[idField])))));
179
+ })),
180
+ helperText != null && (React.createElement(FormHelperText, null, helperText))),
181
+ refresh != null &&
182
+ loadData != null &&
183
+ (typeof refresh === 'string' ? (React.createElement(IconButton, { size: "small", title: refresh, onClick: refreshData },
184
+ React.createElement(RefreshIcon, null))) : (refresh))));
175
185
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -51,15 +51,15 @@
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.96",
54
+ "@etsoo/appscript": "^1.2.97",
55
55
  "@etsoo/notificationbase": "^1.1.7",
56
- "@etsoo/react": "^1.6.2",
57
- "@etsoo/shared": "^1.1.57",
56
+ "@etsoo/react": "^1.6.3",
57
+ "@etsoo/shared": "^1.1.58",
58
58
  "@mui/icons-material": "^5.10.6",
59
59
  "@mui/material": "^5.10.6",
60
60
  "@types/pica": "^9.0.1",
61
61
  "@types/pulltorefreshjs": "^0.1.5",
62
- "@types/react": "^18.0.20",
62
+ "@types/react": "^18.0.21",
63
63
  "@types/react-avatar-editor": "^13.0.0",
64
64
  "@types/react-dom": "^18.0.6",
65
65
  "@types/react-input-mask": "^3.0.1",
@@ -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.4.0",
74
+ "react-router-dom": "^6.4.1",
75
75
  "react-window": "^1.8.7"
76
76
  },
77
77
  "devDependencies": {
@@ -85,13 +85,13 @@
85
85
  "@types/jest": "^29.0.3",
86
86
  "@typescript-eslint/eslint-plugin": "^5.38.0",
87
87
  "@typescript-eslint/parser": "^5.38.0",
88
- "eslint": "^8.23.1",
88
+ "eslint": "^8.24.0",
89
89
  "eslint-config-airbnb-base": "^15.0.0",
90
90
  "eslint-plugin-import": "^2.26.0",
91
91
  "eslint-plugin-react": "^7.31.8",
92
92
  "jest": "^29.0.3",
93
93
  "jest-environment-jsdom": "^29.0.3",
94
- "ts-jest": "^29.0.1",
94
+ "ts-jest": "^29.0.2",
95
95
  "typescript": "^4.8.3"
96
96
  }
97
97
  }
package/src/SelectEx.tsx CHANGED
@@ -2,17 +2,20 @@ import {
2
2
  Checkbox,
3
3
  FormControl,
4
4
  FormHelperText,
5
+ IconButton,
5
6
  InputLabel,
6
7
  ListItemText,
7
8
  MenuItem,
8
9
  OutlinedInput,
9
10
  Select,
10
11
  SelectChangeEvent,
11
- SelectProps
12
+ SelectProps,
13
+ Stack
12
14
  } from '@mui/material';
13
15
  import React from 'react';
14
16
  import { MUGlobal } from './MUGlobal';
15
17
  import { ListItemRightIcon } from './ListItemRightIcon';
18
+ import RefreshIcon from '@mui/icons-material/Refresh';
16
19
  import {
17
20
  DataTypes,
18
21
  IdDefaultType,
@@ -79,11 +82,6 @@ export type SelectExProps<
79
82
  */
80
83
  onItemClick?: (event: React.MouseEvent, option: T) => void;
81
84
 
82
- /**
83
- * Item mouse down handler
84
- */
85
- onItemMouseDown?: (event: React.MouseEvent, option: T) => void;
86
-
87
85
  /**
88
86
  * On load data handler
89
87
  */
@@ -94,6 +92,11 @@ export type SelectExProps<
94
92
  */
95
93
  options?: ReadonlyArray<T>;
96
94
 
95
+ /**
96
+ * Supports refresh label or component
97
+ */
98
+ refresh?: string | React.ReactNode;
99
+
97
100
  /**
98
101
  * Is search case?
99
102
  */
@@ -124,11 +127,11 @@ export function SelectEx<
124
127
  loadData,
125
128
  onItemChange,
126
129
  onItemClick,
127
- onItemMouseDown,
128
130
  onLoadData,
129
131
  multiple = false,
130
132
  name,
131
133
  options,
134
+ refresh,
132
135
  search = false,
133
136
  autoAddBlankItem = search,
134
137
  value,
@@ -232,18 +235,22 @@ export function SelectEx<
232
235
  // Refs
233
236
  const divRef = React.useRef<HTMLDivElement>();
234
237
 
238
+ // Refresh list data
239
+ const refreshData = () => {
240
+ if (loadData == null) return;
241
+ loadData().then((result) => {
242
+ if (result == null || !isMounted.current) return;
243
+ if (onLoadData) onLoadData(result);
244
+ if (autoAddBlankItem) {
245
+ Utils.addBlankItem(result, idField, labelField);
246
+ }
247
+ setOptionsAdd(result);
248
+ });
249
+ };
250
+
235
251
  // When value change
236
252
  React.useEffect(() => {
237
- if (loadData) {
238
- loadData().then((result) => {
239
- if (result == null || !isMounted.current) return;
240
- if (onLoadData) onLoadData(result);
241
- if (autoAddBlankItem) {
242
- Utils.addBlankItem(result, idField, labelField);
243
- }
244
- setOptionsAdd(result);
245
- });
246
- }
253
+ refreshData();
247
254
  }, [localValue]);
248
255
 
249
256
  // When layout ready
@@ -263,101 +270,122 @@ export function SelectEx<
263
270
 
264
271
  // Layout
265
272
  return (
266
- <FormControl
267
- size={search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize}
268
- fullWidth={fullWidth}
269
- error={error}
270
- >
271
- <InputLabel
272
- id={labelId}
273
- shrink={
274
- search
275
- ? MUGlobal.searchFieldShrink
276
- : MUGlobal.inputFieldShrink
273
+ <Stack direction="row">
274
+ <FormControl
275
+ size={
276
+ search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize
277
277
  }
278
- >
279
- {label}
280
- </InputLabel>
281
- <Select
282
- ref={divRef}
283
- value={
284
- localOptions.some((option) => itemChecked(getId(option)))
285
- ? valueState ?? ''
286
- : ''
287
- }
288
- input={
289
- <OutlinedInput
290
- notched
291
- label={label}
292
- required={inputRequired}
293
- />
294
- }
295
- labelId={labelId}
296
- name={name}
297
- multiple={multiple}
298
- onChange={(event, child) => {
299
- if (onChange) onChange(event, child);
300
- doItemChange(localOptions, event.target.value, true);
301
- handleChange(event);
302
- }}
303
- renderValue={(selected) => {
304
- // The text shows up
305
- return localOptions
306
- .filter((option) => {
307
- const id = getId(option);
308
- return Array.isArray(selected)
309
- ? selected.indexOf(id) !== -1
310
- : selected === id;
311
- })
312
- .map((option) => getLabel(option))
313
- .join(', ');
314
- }}
315
- sx={{ minWidth: '150px' }}
316
278
  fullWidth={fullWidth}
317
- {...rest}
279
+ error={error}
318
280
  >
319
- {localOptions.map((option) => {
320
- // Option id
321
- const id = getId(option);
322
-
323
- // Option label
324
- const label = getLabel(option);
325
-
326
- // Option
327
- return (
328
- <MenuItem
329
- key={id}
330
- value={id}
331
- onClick={(event) => {
332
- if (onItemClick) {
333
- onItemClick(event, option);
334
- }
335
- }}
336
- onMouseDown={(event) => {
337
- if (onItemMouseDown) {
338
- onItemMouseDown(event, option);
281
+ <InputLabel
282
+ id={labelId}
283
+ shrink={
284
+ search
285
+ ? MUGlobal.searchFieldShrink
286
+ : MUGlobal.inputFieldShrink
287
+ }
288
+ >
289
+ {label}
290
+ </InputLabel>
291
+ <Select
292
+ ref={divRef}
293
+ value={
294
+ localOptions.some((option) =>
295
+ itemChecked(getId(option))
296
+ )
297
+ ? valueState ?? ''
298
+ : ''
299
+ }
300
+ input={
301
+ <OutlinedInput
302
+ notched
303
+ label={label}
304
+ required={inputRequired}
305
+ />
306
+ }
307
+ labelId={labelId}
308
+ name={name}
309
+ multiple={multiple}
310
+ onChange={(event, child) => {
311
+ if (onChange) {
312
+ onChange(event, child);
313
+
314
+ // event.preventDefault() will block executing
315
+ if (event.defaultPrevented) return;
316
+ }
317
+ doItemChange(localOptions, event.target.value, true);
318
+ handleChange(event);
319
+ }}
320
+ renderValue={(selected) => {
321
+ // The text shows up
322
+ return localOptions
323
+ .filter((option) => {
324
+ const id = getId(option);
325
+ return Array.isArray(selected)
326
+ ? selected.indexOf(id) !== -1
327
+ : selected === id;
328
+ })
329
+ .map((option) => getLabel(option))
330
+ .join(', ');
331
+ }}
332
+ sx={{ minWidth: '150px' }}
333
+ fullWidth={fullWidth}
334
+ {...rest}
335
+ >
336
+ {localOptions.map((option) => {
337
+ // Option id
338
+ const id = getId(option);
339
+
340
+ // Option label
341
+ const label = getLabel(option);
342
+
343
+ // Option
344
+ return (
345
+ <MenuItem
346
+ key={id}
347
+ value={id}
348
+ onClick={(event) => {
349
+ if (onItemClick) {
350
+ onItemClick(event, option);
351
+ }
352
+ }}
353
+ style={
354
+ itemStyle == null
355
+ ? undefined
356
+ : itemStyle(option)
339
357
  }
340
- }}
341
- style={
342
- itemStyle == null
343
- ? undefined
344
- : itemStyle(option)
345
- }
346
- >
347
- {multiple && <Checkbox checked={itemChecked(id)} />}
348
- <ListItemText primary={label} />
349
- {itemIconRenderer && (
350
- <ListItemRightIcon>
351
- {itemIconRenderer(option[idField])}
352
- </ListItemRightIcon>
353
- )}
354
- </MenuItem>
355
- );
356
- })}
357
- </Select>
358
- {helperText != null && (
359
- <FormHelperText>{helperText}</FormHelperText>
360
- )}
361
- </FormControl>
358
+ >
359
+ {multiple && (
360
+ <Checkbox checked={itemChecked(id)} />
361
+ )}
362
+ <ListItemText primary={label} />
363
+ {itemIconRenderer && (
364
+ <ListItemRightIcon>
365
+ {itemIconRenderer(option[idField])}
366
+ </ListItemRightIcon>
367
+ )}
368
+ </MenuItem>
369
+ );
370
+ })}
371
+ </Select>
372
+ {helperText != null && (
373
+ <FormHelperText>{helperText}</FormHelperText>
374
+ )}
375
+ </FormControl>
376
+ {refresh != null &&
377
+ loadData != null &&
378
+ (typeof refresh === 'string' ? (
379
+ <IconButton
380
+ size="small"
381
+ title={refresh}
382
+ onClick={refreshData}
383
+ >
384
+ <RefreshIcon />
385
+ </IconButton>
386
+ ) : (
387
+ refresh
388
+ ))}
389
+ </Stack>
362
390
  );
363
391
  }