@etsoo/materialui 1.2.89 → 1.2.91

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/ComboBox.js CHANGED
@@ -113,7 +113,7 @@ export function ComboBox(props) {
113
113
  }, []);
114
114
  // Layout
115
115
  return (React.createElement("div", null,
116
- React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: "none" }, name: name, value: getValue(stateValue), readOnly: true, onChange: inputOnChange }),
116
+ React.createElement("input", { ref: inputRef, "data-reset": inputReset !== null && inputReset !== void 0 ? inputReset : true, type: "text", style: { display: "none" }, name: name, value: getValue(stateValue), readOnly: true, onChange: inputOnChange }),
117
117
  React.createElement(Stack, { gap: 0.5, direction: "row", width: "100%" },
118
118
  React.createElement(Autocomplete, { value: stateValue, disableCloseOnSelect: disableCloseOnSelect, getOptionLabel: getOptionLabel, isOptionEqualToValue: (option, value) => option[idField] === value[idField], onChange: (event, value, reason, details) => {
119
119
  // Set value
@@ -115,7 +115,7 @@ export function ComboBoxMultiple(props) {
115
115
  }, []);
116
116
  // Layout
117
117
  return (React.createElement("div", null,
118
- React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: "none" }, name: name, value: getValue(stateValue), readOnly: true, onChange: inputOnChange }),
118
+ React.createElement("input", { ref: inputRef, "data-reset": inputReset !== null && inputReset !== void 0 ? inputReset : true, type: "text", style: { display: "none" }, name: name, value: getValue(stateValue), readOnly: true, onChange: inputOnChange }),
119
119
  React.createElement(Autocomplete, { value: stateValue == null
120
120
  ? []
121
121
  : Array.isArray(stateValue)
@@ -4,10 +4,24 @@ import React from "react";
4
4
  * File upload button props
5
5
  */
6
6
  export type FileUploadButtonProps = ButtonProps<"label"> & {
7
+ /**
8
+ * Max files allowed
9
+ */
10
+ maxFiles?: number;
11
+ /**
12
+ * Max file size
13
+ */
14
+ maxFileSize?: number;
7
15
  /**
8
16
  * Input field attributes
9
17
  */
10
18
  inputProps?: Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "hidden">;
19
+ /**
20
+ * File invalid handler
21
+ * @param values [expected, actual]
22
+ * @param file File
23
+ */
24
+ onFileInvalid?: (values: [number, number], file?: File) => void;
11
25
  /**
12
26
  * Upload files callback
13
27
  * @param files Files
@@ -7,7 +7,7 @@ import React from "react";
7
7
  */
8
8
  export function FileUploadButton(props) {
9
9
  // Destruct
10
- const { inputProps, onUploadFiles, children, ...rest } = props;
10
+ const { maxFiles, maxFileSize, inputProps, onFileInvalid, onUploadFiles, children, ...rest } = props;
11
11
  const { onChange } = inputProps !== null && inputProps !== void 0 ? inputProps : {};
12
12
  // Layout
13
13
  return (React.createElement(Button, { component: "label", ...rest },
@@ -19,8 +19,26 @@ export function FileUploadButton(props) {
19
19
  return;
20
20
  if (onUploadFiles) {
21
21
  const files = event.target.files;
22
- if (files == null || files.length == 0)
22
+ if (files == null)
23
23
  return;
24
+ const fl = files.length;
25
+ if (fl === 0)
26
+ return;
27
+ if (maxFiles && maxFiles > 0 && fl > maxFiles) {
28
+ if (onFileInvalid)
29
+ onFileInvalid([maxFiles, fl]);
30
+ return;
31
+ }
32
+ if (maxFileSize && maxFileSize > 0) {
33
+ for (let f = 0; f < fl; f++) {
34
+ const file = files[f];
35
+ if (file.size > maxFileSize) {
36
+ if (onFileInvalid)
37
+ onFileInvalid([maxFileSize, file.size], file);
38
+ return;
39
+ }
40
+ }
41
+ }
24
42
  onUploadFiles(files);
25
43
  }
26
44
  }, ...inputProps })));
package/lib/Tiplist.js CHANGED
@@ -166,7 +166,7 @@ export function Tiplist(props) {
166
166
  }, []);
167
167
  // Layout
168
168
  return (React.createElement("div", null,
169
- React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: "none" }, name: name, value: `${inputValue !== null && inputValue !== void 0 ? inputValue : (state.current.idSet ? "" : localIdValue !== null && localIdValue !== void 0 ? localIdValue : "")}`, readOnly: true, onChange: inputOnChange }),
169
+ React.createElement("input", { ref: inputRef, "data-reset": inputReset !== null && inputReset !== void 0 ? inputReset : true, type: "text", style: { display: "none" }, name: name, value: `${inputValue !== null && inputValue !== void 0 ? inputValue : (state.current.idSet ? "" : localIdValue !== null && localIdValue !== void 0 ? localIdValue : "")}`, readOnly: true, onChange: inputOnChange }),
170
170
  React.createElement(Autocomplete, { filterOptions: (options, _state) => options, value: states.value, options: states.options, onChange: (event, value, reason, details) => {
171
171
  // Set value
172
172
  setInputValue(value);
@@ -38,6 +38,10 @@ export type TiplistProProps<T extends ListType2 = ListType2> = Omit<Autocomplete
38
38
  * Input props
39
39
  */
40
40
  inputProps?: Omit<InputFieldProps, "onChange">;
41
+ /**
42
+ * Set 'data-reset'
43
+ */
44
+ inputReset?: boolean;
41
45
  /**
42
46
  * Value change handler
43
47
  * @param value New value
package/lib/TiplistPro.js CHANGED
@@ -13,7 +13,7 @@ export function TiplistPro(props) {
13
13
  // Labels
14
14
  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 : {};
15
15
  // Destruct
16
- const { label, loadData, defaultValue, value, idValue, maxItems = 16, width, name, inputOnChange, inputProps, sx, openOnFocus = true, noOptionsText = noOptions, loadingText = loading, openText = openDefault, getOptionDisabled, getOptionLabel, onChange, onValueChange, ...rest } = props;
16
+ const { label, loadData, defaultValue, value, idValue, maxItems = 16, width, name, inputOnChange, inputProps, inputReset, sx, openOnFocus = true, noOptionsText = noOptions, loadingText = loading, openText = openDefault, getOptionDisabled, getOptionLabel, onChange, onValueChange, ...rest } = props;
17
17
  if (width && sx)
18
18
  Object.assign(sx, { width: `${width}px` });
19
19
  // Value input ref
@@ -150,7 +150,7 @@ export function TiplistPro(props) {
150
150
  }, []);
151
151
  // Layout
152
152
  return (React.createElement("div", null,
153
- React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: "none" }, name: name, value: inputValue !== null && inputValue !== void 0 ? inputValue : (state.current.idSet ? "" : localIdValue !== null && localIdValue !== void 0 ? localIdValue : ""), readOnly: true, onChange: inputOnChange }),
153
+ React.createElement("input", { ref: inputRef, "data-reset": inputReset !== null && inputReset !== void 0 ? inputReset : true, type: "text", style: { display: "none" }, name: name, value: inputValue !== null && inputValue !== void 0 ? inputValue : (state.current.idSet ? "" : localIdValue !== null && localIdValue !== void 0 ? localIdValue : ""), readOnly: true, onChange: inputOnChange }),
154
154
  React.createElement(Autocomplete, { filterOptions: (options, _state) => options, value: states.value, options: states.options, freeSolo: true, clearOnBlur: false, onChange: (event, value, reason, details) => {
155
155
  if (typeof value === "object") {
156
156
  // Set value
@@ -185,7 +185,7 @@ export function TiplistPro(props) {
185
185
  }, loading: states.loading, renderInput: (params) => (React.createElement(InputField, { ...inputProps, ...params, onChange: changeHandle, label: label, name: name + "Input", onBlur: (event) => {
186
186
  if (states.value == null && onChange)
187
187
  onChange(event, event.target.value, "blur", undefined);
188
- } })), isOptionEqualToValue: (option, value) => option.id === value.id, sx: sx, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionDisabled: (item) => {
188
+ }, "data-reset": inputReset })), isOptionEqualToValue: (option, value) => option.id === value.id, sx: sx, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionDisabled: (item) => {
189
189
  if (item.id === -1)
190
190
  return true;
191
191
  return getOptionDisabled ? getOptionDisabled(item) : false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.2.89",
3
+ "version": "1.2.91",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -53,10 +53,10 @@
53
53
  "@etsoo/appscript": "^1.4.32",
54
54
  "@etsoo/notificationbase": "^1.1.26",
55
55
  "@etsoo/react": "^1.7.3",
56
- "@etsoo/shared": "^1.2.8",
57
- "@mui/icons-material": "^5.14.6",
58
- "@mui/material": "^5.14.6",
59
- "@mui/x-data-grid": "^6.11.2",
56
+ "@etsoo/shared": "^1.2.9",
57
+ "@mui/icons-material": "^5.14.7",
58
+ "@mui/material": "^5.14.7",
59
+ "@mui/x-data-grid": "^6.12.0",
60
60
  "@types/pica": "^9.0.1",
61
61
  "@types/pulltorefreshjs": "^0.1.5",
62
62
  "@types/react": "^18.2.21",
@@ -85,8 +85,8 @@
85
85
  "@testing-library/jest-dom": "^6.1.2",
86
86
  "@testing-library/react": "^14.0.0",
87
87
  "@types/jest": "^29.5.4",
88
- "@typescript-eslint/eslint-plugin": "^6.4.1",
89
- "@typescript-eslint/parser": "^6.4.1",
88
+ "@typescript-eslint/eslint-plugin": "^6.5.0",
89
+ "@typescript-eslint/parser": "^6.5.0",
90
90
  "jest": "^29.6.4",
91
91
  "jest-environment-jsdom": "^29.6.4",
92
92
  "typescript": "^5.2.2"
package/src/ComboBox.tsx CHANGED
@@ -234,7 +234,7 @@ export function ComboBox<
234
234
  <div>
235
235
  <input
236
236
  ref={inputRef}
237
- data-reset="true"
237
+ data-reset={inputReset ?? true}
238
238
  type="text"
239
239
  style={{ display: "none" }}
240
240
  name={name}
@@ -242,7 +242,7 @@ export function ComboBoxMultiple<
242
242
  <div>
243
243
  <input
244
244
  ref={inputRef}
245
- data-reset="true"
245
+ data-reset={inputReset ?? true}
246
246
  type="text"
247
247
  style={{ display: "none" }}
248
248
  name={name}
@@ -5,6 +5,16 @@ import React from "react";
5
5
  * File upload button props
6
6
  */
7
7
  export type FileUploadButtonProps = ButtonProps<"label"> & {
8
+ /**
9
+ * Max files allowed
10
+ */
11
+ maxFiles?: number;
12
+
13
+ /**
14
+ * Max file size
15
+ */
16
+ maxFileSize?: number;
17
+
8
18
  /**
9
19
  * Input field attributes
10
20
  */
@@ -13,6 +23,13 @@ export type FileUploadButtonProps = ButtonProps<"label"> & {
13
23
  "type" | "hidden"
14
24
  >;
15
25
 
26
+ /**
27
+ * File invalid handler
28
+ * @param values [expected, actual]
29
+ * @param file File
30
+ */
31
+ onFileInvalid?: (values: [number, number], file?: File) => void;
32
+
16
33
  /**
17
34
  * Upload files callback
18
35
  * @param files Files
@@ -27,7 +44,15 @@ export type FileUploadButtonProps = ButtonProps<"label"> & {
27
44
  */
28
45
  export function FileUploadButton(props: FileUploadButtonProps) {
29
46
  // Destruct
30
- const { inputProps, onUploadFiles, children, ...rest } = props;
47
+ const {
48
+ maxFiles,
49
+ maxFileSize,
50
+ inputProps,
51
+ onFileInvalid,
52
+ onUploadFiles,
53
+ children,
54
+ ...rest
55
+ } = props;
31
56
 
32
57
  const { onChange } = inputProps ?? {};
33
58
 
@@ -44,7 +69,27 @@ export function FileUploadButton(props: FileUploadButtonProps) {
44
69
 
45
70
  if (onUploadFiles) {
46
71
  const files = event.target.files;
47
- if (files == null || files.length == 0) return;
72
+ if (files == null) return;
73
+
74
+ const fl = files.length;
75
+ if (fl === 0) return;
76
+
77
+ if (maxFiles && maxFiles > 0 && fl > maxFiles) {
78
+ if (onFileInvalid) onFileInvalid([maxFiles, fl]);
79
+ return;
80
+ }
81
+
82
+ if (maxFileSize && maxFileSize > 0) {
83
+ for (let f = 0; f < fl; f++) {
84
+ const file = files[f];
85
+ if (file.size > maxFileSize) {
86
+ if (onFileInvalid)
87
+ onFileInvalid([maxFileSize, file.size], file);
88
+ return;
89
+ }
90
+ }
91
+ }
92
+
48
93
  onUploadFiles(files);
49
94
  }
50
95
  }}
package/src/Tiplist.tsx CHANGED
@@ -275,7 +275,7 @@ export function Tiplist<
275
275
  <div>
276
276
  <input
277
277
  ref={inputRef}
278
- data-reset="true"
278
+ data-reset={inputReset ?? true}
279
279
  type="text"
280
280
  style={{ display: "none" }}
281
281
  name={name}
@@ -56,6 +56,11 @@ export type TiplistProProps<T extends ListType2 = ListType2> = Omit<
56
56
  */
57
57
  inputProps?: Omit<InputFieldProps, "onChange">;
58
58
 
59
+ /**
60
+ * Set 'data-reset'
61
+ */
62
+ inputReset?: boolean;
63
+
59
64
  /**
60
65
  * Value change handler
61
66
  * @param value New value
@@ -99,6 +104,7 @@ export function TiplistPro<T extends ListType2 = ListType2>(
99
104
  name,
100
105
  inputOnChange,
101
106
  inputProps,
107
+ inputReset,
102
108
  sx,
103
109
  openOnFocus = true,
104
110
  noOptionsText = noOptions,
@@ -278,7 +284,7 @@ export function TiplistPro<T extends ListType2 = ListType2>(
278
284
  <div>
279
285
  <input
280
286
  ref={inputRef}
281
- data-reset="true"
287
+ data-reset={inputReset ?? true}
282
288
  type="text"
283
289
  style={{ display: "none" }}
284
290
  name={name}
@@ -348,6 +354,7 @@ export function TiplistPro<T extends ListType2 = ListType2>(
348
354
  if (states.value == null && onChange)
349
355
  onChange(event, event.target.value, "blur", undefined);
350
356
  }}
357
+ data-reset={inputReset}
351
358
  />
352
359
  )}
353
360
  isOptionEqualToValue={(option, value) => option.id === value.id}