@etsoo/materialui 1.5.98 → 1.5.99

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.
@@ -5,21 +5,17 @@ import { TextFieldProps } from "@mui/material/TextField";
5
5
  */
6
6
  export type InputFieldProps = TextFieldProps & {
7
7
  /**
8
- * Change delay (ms) to avoid repeatly dispatch onChange
8
+ * Change [delay (ms), Minimum characters] to avoid repeatly dispatch
9
9
  */
10
- changeDelay?: number;
10
+ changeDelay?: [number, number?];
11
11
  /**
12
- * Change delay handler, without it onChange will be applied
12
+ * Change delay handler
13
13
  */
14
14
  onChangeDelay?: React.ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement>;
15
15
  /**
16
16
  * Is the field read only?
17
17
  */
18
18
  readOnly?: boolean;
19
- /**
20
- * Minimum characters to trigger the change event
21
- */
22
- minChars?: number;
23
19
  };
24
20
  /**
25
21
  * Input field
@@ -16,31 +16,29 @@ const TextField_1 = __importDefault(require("@mui/material/TextField"));
16
16
  */
17
17
  function InputField(props) {
18
18
  // Destruct
19
- const { InputProps = {}, inputProps = {}, slotProps, changeDelay, onChange, onChangeDelay, readOnly, size = MUGlobal_1.MUGlobal.inputFieldSize, variant = MUGlobal_1.MUGlobal.inputFieldVariant, minChars = 0, ...rest } = props;
19
+ const { InputProps = {}, inputProps = {}, slotProps, onChange, onChangeDelay, changeDelay = onChangeDelay ? [480] : undefined, readOnly, size = MUGlobal_1.MUGlobal.inputFieldSize, variant = MUGlobal_1.MUGlobal.inputFieldVariant, ...rest } = props;
20
20
  // Slot props
21
21
  const { htmlInput, input, inputLabel, ...restSlotProps } = slotProps ?? {};
22
22
  const isMounted = react_2.default.useRef(true);
23
23
  const createDelayed = () => {
24
- if (changeDelay != null && changeDelay >= 1) {
25
- const changeHandler = onChangeDelay ?? onChange;
26
- if (changeHandler)
27
- return (0, react_1.useDelayedExecutor)(changeHandler, changeDelay);
24
+ if (onChangeDelay && changeDelay && changeDelay[0] >= 1) {
25
+ return (0, react_1.useDelayedExecutor)(onChangeDelay, changeDelay[0]);
28
26
  }
29
27
  return undefined;
30
28
  };
31
29
  const delayed = createDelayed();
32
30
  const onChangeEx = (event) => {
33
- // Min characters check
34
- const len = event.target.value.length;
35
- if (len > 0 && len < minChars) {
36
- // Avoid to trigger the form change event
37
- event.stopPropagation();
38
- event.preventDefault();
39
- return;
31
+ // Change handler
32
+ onChange?.(event);
33
+ if (onChangeDelay && changeDelay && delayed) {
34
+ const [_, minChars = 0] = changeDelay;
35
+ if (minChars > 0) {
36
+ const len = event.target.value.length;
37
+ if (len < minChars)
38
+ return;
39
+ }
40
+ delayed.call(undefined, event);
40
41
  }
41
- if (onChange && (delayed == null || onChangeDelay != null))
42
- onChange(event);
43
- delayed?.call(undefined, event);
44
42
  };
45
43
  react_2.default.useEffect(() => {
46
44
  return () => {
@@ -51,7 +49,7 @@ function InputField(props) {
51
49
  // Layout
52
50
  return ((0, jsx_runtime_1.jsx)(TextField_1.default, { slotProps: {
53
51
  htmlInput: {
54
- ["data-min-chars"]: minChars,
52
+ ["data-min-chars"]: changeDelay?.[1],
55
53
  ...htmlInput,
56
54
  ...inputProps
57
55
  },
@@ -35,7 +35,7 @@ function InputTipField(props) {
35
35
  const [anchorEl, setAnchorEl] = react_1.default.useState();
36
36
  const [data, setData] = react_1.default.useState();
37
37
  // Destruct
38
- const { component = "input", componentProps, changeDelay = 480, onChangeDelay, fullWidth = true, slotProps = {}, ...rest } = props;
38
+ const { component = "input", componentProps, changeDelay, onChangeDelay, fullWidth = true, slotProps = {}, ...rest } = props;
39
39
  const { labelProps = {
40
40
  title: app?.get("clickForDetails"),
41
41
  sx: { color: (theme) => theme.palette.error.main, cursor: "pointer" }
@@ -18,7 +18,7 @@ const IconButton_1 = __importDefault(require("@mui/material/IconButton"));
18
18
  */
19
19
  function IntInputField(props) {
20
20
  // Destruct
21
- const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = 600, onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props;
21
+ const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = [600], onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props;
22
22
  // State
23
23
  const [localValue, setLocalValue] = react_1.default.useState();
24
24
  const setValue = (value, source, init = false) => {
@@ -40,7 +40,7 @@ function QuickList(props) {
40
40
  loadDataLocal();
41
41
  }, []);
42
42
  // Layout
43
- return ((0, jsx_runtime_1.jsxs)(FlexBox_1.VBox, { gap: gap, height: height, ...rest, children: [(0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, changeDelay: 480, onChangeDelay: (event) => {
43
+ return ((0, jsx_runtime_1.jsxs)(FlexBox_1.VBox, { gap: gap, height: height, ...rest, children: [(0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, onChangeDelay: (event) => {
44
44
  // Stop bubble
45
45
  event.preventDefault();
46
46
  event.stopPropagation();
@@ -12,7 +12,7 @@ export type TagListProps = Omit<AutocompleteProps<string, true, false, true>, "o
12
12
  /**
13
13
  * Input props
14
14
  */
15
- inputProps?: Omit<InputFieldProps, "onChange">;
15
+ inputProps?: Omit<InputFieldProps, "onChangeDelay">;
16
16
  /**
17
17
  * Max items
18
18
  */
@@ -20,7 +20,7 @@ function TagList(props) {
20
20
  const { noOptions, loading: loadingLabel, more = "More", open: openDefault } = app?.getLabels("noOptions", "loading", "more", "open") ?? {};
21
21
  const moreLabel = more + "...";
22
22
  // Destruct
23
- const { renderOption = ({ key, ...props }, option, { selected }) => ((0, jsx_runtime_1.jsxs)("li", { ...props, children: [(0, jsx_runtime_1.jsx)(Checkbox_1.default, { icon: (0, jsx_runtime_1.jsx)(CheckBoxOutlineBlank_1.default, { fontSize: "small" }), checkedIcon: (0, jsx_runtime_1.jsx)(CheckBox_1.default, { fontSize: "small" }), style: { marginRight: 8 }, checked: selected }), option] }, key)), renderTags = (value, getTagProps) => value.map((option, index) => {
23
+ const { renderOption = ({ key, ...props }, option, { selected }) => ((0, jsx_runtime_1.jsxs)("li", { ...props, children: [(0, jsx_runtime_1.jsx)(Checkbox_1.default, { icon: (0, jsx_runtime_1.jsx)(CheckBoxOutlineBlank_1.default, { fontSize: "small" }), checkedIcon: (0, jsx_runtime_1.jsx)(CheckBox_1.default, { fontSize: "small" }), style: { marginRight: 8 }, checked: selected }), option] }, key)), renderValue = (value, getTagProps) => value.map((option, index) => {
24
24
  const { key, ...rest } = getTagProps({ index });
25
25
  return (0, jsx_runtime_1.jsx)(Chip_1.default, { variant: "outlined", label: option, ...rest }, key);
26
26
  }), noOptionsText = noOptions, loadingText = loadingLabel, openText = openDefault, loadData, maxItems = 16, disableCloseOnSelect = true, openOnFocus = true, label, inputProps, onChange, value, ...rest } = props;
@@ -54,7 +54,7 @@ function TagList(props) {
54
54
  }
55
55
  }, onClose: () => {
56
56
  setOpen(false);
57
- }, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, clearOnBlur: true, openOnFocus: openOnFocus, renderOption: renderOption, renderTags: renderTags, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, changeDelay: 480, onChange: async (event) => {
57
+ }, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, clearOnBlur: true, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, onChangeDelay: async (event) => {
58
58
  // Stop bubble
59
59
  event.preventDefault();
60
60
  event.stopPropagation();
@@ -13,7 +13,7 @@ export type TagListProProps<D extends ListType2 = ListType2> = Omit<Autocomplete
13
13
  /**
14
14
  * Input props
15
15
  */
16
- inputProps?: Omit<InputFieldProps, "onChange">;
16
+ inputProps?: Omit<InputFieldProps, "onChangeDelay">;
17
17
  /**
18
18
  * Max items
19
19
  */
@@ -56,7 +56,7 @@ function TagListPro(props) {
56
56
  }
57
57
  }, onClose: () => {
58
58
  setOpen(false);
59
- }, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, changeDelay: 480, onChange: async (event) => {
59
+ }, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { label: label, onChangeDelay: async (event) => {
60
60
  // Stop bubble
61
61
  event.preventDefault();
62
62
  event.stopPropagation();
@@ -77,8 +77,12 @@ function Tiplist(props) {
77
77
  }
78
78
  // Stop bubble
79
79
  event.stopPropagation();
80
+ const value = event.currentTarget.value;
81
+ if (minChars && minChars > 0 && value.length < minChars) {
82
+ return;
83
+ }
80
84
  // Call with delay
81
- delayed.call(undefined, event.currentTarget.value);
85
+ delayed.call(undefined, value);
82
86
  };
83
87
  // Directly load data
84
88
  const loadDataDirect = (keyword, id) => {
@@ -197,7 +201,7 @@ function Tiplist(props) {
197
201
  open: false,
198
202
  ...(!states.value && { options: [] })
199
203
  });
200
- }, loading: states.loading, renderInput: (params) => search ? ((0, jsx_runtime_1.jsx)(SearchField_1.SearchField, { onChange: changeHandle, ...addReadOnly(params), readOnly: readOnly, label: label, name: name + "Input", margin: inputMargin, minChars: minChars, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })) : ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { onChange: changeHandle, ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, minChars: minChars, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })), isOptionEqualToValue: (option, value) => option[idField] === value[idField], sx: sx, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionDisabled: (item) => {
204
+ }, loading: states.loading, renderInput: (params) => search ? ((0, jsx_runtime_1.jsx)(SearchField_1.SearchField, { onChange: changeHandle, ...addReadOnly(params), readOnly: readOnly, label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })) : ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { onChange: changeHandle, ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })), isOptionEqualToValue: (option, value) => option[idField] === value[idField], sx: sx, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionDisabled: (item) => {
201
205
  if (item[idField] === "n/a")
202
206
  return true;
203
207
  return getOptionDisabled ? getOptionDisabled(item) : false;
@@ -66,8 +66,12 @@ function TiplistPro(props) {
66
66
  }
67
67
  // Stop bubble
68
68
  event.stopPropagation();
69
+ const value = event.currentTarget.value;
70
+ if (minChars && minChars > 0 && value.length < minChars) {
71
+ return;
72
+ }
69
73
  // Call with delay
70
- delayed.call(undefined, event.currentTarget.value);
74
+ delayed.call(undefined, value);
71
75
  };
72
76
  // Directly load data
73
77
  const loadDataDirect = (keyword, id) => {
@@ -189,7 +193,7 @@ function TiplistPro(props) {
189
193
  open: false,
190
194
  ...(!states.value && { options: [] })
191
195
  });
192
- }, loading: states.loading, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { minChars: minChars, ...inputProps, ...params, onChange: changeHandle, label: label, name: name + "Input", onBlur: (event) => {
196
+ }, loading: states.loading, renderInput: (params) => ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { ...inputProps, ...params, onChange: changeHandle, label: label, name: name + "Input", onBlur: (event) => {
193
197
  if (states.value == null && onChange)
194
198
  onChange(event, event.target.value, "blur", undefined);
195
199
  }, "data-reset": inputReset })), isOptionEqualToValue: (option, value) => option.id === value.id, sx: sx, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionKey: getOptionKey, getOptionDisabled: (item) => {
@@ -5,21 +5,17 @@ import { TextFieldProps } from "@mui/material/TextField";
5
5
  */
6
6
  export type InputFieldProps = TextFieldProps & {
7
7
  /**
8
- * Change delay (ms) to avoid repeatly dispatch onChange
8
+ * Change [delay (ms), Minimum characters] to avoid repeatly dispatch
9
9
  */
10
- changeDelay?: number;
10
+ changeDelay?: [number, number?];
11
11
  /**
12
- * Change delay handler, without it onChange will be applied
12
+ * Change delay handler
13
13
  */
14
14
  onChangeDelay?: React.ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement>;
15
15
  /**
16
16
  * Is the field read only?
17
17
  */
18
18
  readOnly?: boolean;
19
- /**
20
- * Minimum characters to trigger the change event
21
- */
22
- minChars?: number;
23
19
  };
24
20
  /**
25
21
  * Input field
@@ -10,31 +10,29 @@ import TextField from "@mui/material/TextField";
10
10
  */
11
11
  export function InputField(props) {
12
12
  // Destruct
13
- const { InputProps = {}, inputProps = {}, slotProps, changeDelay, onChange, onChangeDelay, readOnly, size = MUGlobal.inputFieldSize, variant = MUGlobal.inputFieldVariant, minChars = 0, ...rest } = props;
13
+ const { InputProps = {}, inputProps = {}, slotProps, onChange, onChangeDelay, changeDelay = onChangeDelay ? [480] : undefined, readOnly, size = MUGlobal.inputFieldSize, variant = MUGlobal.inputFieldVariant, ...rest } = props;
14
14
  // Slot props
15
15
  const { htmlInput, input, inputLabel, ...restSlotProps } = slotProps ?? {};
16
16
  const isMounted = React.useRef(true);
17
17
  const createDelayed = () => {
18
- if (changeDelay != null && changeDelay >= 1) {
19
- const changeHandler = onChangeDelay ?? onChange;
20
- if (changeHandler)
21
- return useDelayedExecutor(changeHandler, changeDelay);
18
+ if (onChangeDelay && changeDelay && changeDelay[0] >= 1) {
19
+ return useDelayedExecutor(onChangeDelay, changeDelay[0]);
22
20
  }
23
21
  return undefined;
24
22
  };
25
23
  const delayed = createDelayed();
26
24
  const onChangeEx = (event) => {
27
- // Min characters check
28
- const len = event.target.value.length;
29
- if (len > 0 && len < minChars) {
30
- // Avoid to trigger the form change event
31
- event.stopPropagation();
32
- event.preventDefault();
33
- return;
25
+ // Change handler
26
+ onChange?.(event);
27
+ if (onChangeDelay && changeDelay && delayed) {
28
+ const [_, minChars = 0] = changeDelay;
29
+ if (minChars > 0) {
30
+ const len = event.target.value.length;
31
+ if (len < minChars)
32
+ return;
33
+ }
34
+ delayed.call(undefined, event);
34
35
  }
35
- if (onChange && (delayed == null || onChangeDelay != null))
36
- onChange(event);
37
- delayed?.call(undefined, event);
38
36
  };
39
37
  React.useEffect(() => {
40
38
  return () => {
@@ -45,7 +43,7 @@ export function InputField(props) {
45
43
  // Layout
46
44
  return (_jsx(TextField, { slotProps: {
47
45
  htmlInput: {
48
- ["data-min-chars"]: minChars,
46
+ ["data-min-chars"]: changeDelay?.[1],
49
47
  ...htmlInput,
50
48
  ...inputProps
51
49
  },
@@ -29,7 +29,7 @@ export function InputTipField(props) {
29
29
  const [anchorEl, setAnchorEl] = React.useState();
30
30
  const [data, setData] = React.useState();
31
31
  // Destruct
32
- const { component = "input", componentProps, changeDelay = 480, onChangeDelay, fullWidth = true, slotProps = {}, ...rest } = props;
32
+ const { component = "input", componentProps, changeDelay, onChangeDelay, fullWidth = true, slotProps = {}, ...rest } = props;
33
33
  const { labelProps = {
34
34
  title: app?.get("clickForDetails"),
35
35
  sx: { color: (theme) => theme.palette.error.main, cursor: "pointer" }
@@ -12,7 +12,7 @@ import IconButton from "@mui/material/IconButton";
12
12
  */
13
13
  export function IntInputField(props) {
14
14
  // Destruct
15
- const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = 600, onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props;
15
+ const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, boxProps, buttons, endSymbol, symbol, value, changeDelay = [600], onChangeDelay, onChange, onFocus = (event) => event.currentTarget.select(), onValueChange, required, ...rest } = props;
16
16
  // State
17
17
  const [localValue, setLocalValue] = React.useState();
18
18
  const setValue = (value, source, init = false) => {
@@ -34,7 +34,7 @@ export function QuickList(props) {
34
34
  loadDataLocal();
35
35
  }, []);
36
36
  // Layout
37
- return (_jsxs(VBox, { gap: gap, height: height, ...rest, children: [_jsx(InputField, { label: label, changeDelay: 480, onChangeDelay: (event) => {
37
+ return (_jsxs(VBox, { gap: gap, height: height, ...rest, children: [_jsx(InputField, { label: label, onChangeDelay: (event) => {
38
38
  // Stop bubble
39
39
  event.preventDefault();
40
40
  event.stopPropagation();
@@ -12,7 +12,7 @@ export type TagListProps = Omit<AutocompleteProps<string, true, false, true>, "o
12
12
  /**
13
13
  * Input props
14
14
  */
15
- inputProps?: Omit<InputFieldProps, "onChange">;
15
+ inputProps?: Omit<InputFieldProps, "onChangeDelay">;
16
16
  /**
17
17
  * Max items
18
18
  */
@@ -14,7 +14,7 @@ export function TagList(props) {
14
14
  const { noOptions, loading: loadingLabel, more = "More", open: openDefault } = app?.getLabels("noOptions", "loading", "more", "open") ?? {};
15
15
  const moreLabel = more + "...";
16
16
  // Destruct
17
- const { renderOption = ({ key, ...props }, option, { selected }) => (_jsxs("li", { ...props, children: [_jsx(Checkbox, { icon: _jsx(CheckBoxOutlineBlankIcon, { fontSize: "small" }), checkedIcon: _jsx(CheckBoxIcon, { fontSize: "small" }), style: { marginRight: 8 }, checked: selected }), option] }, key)), renderTags = (value, getTagProps) => value.map((option, index) => {
17
+ const { renderOption = ({ key, ...props }, option, { selected }) => (_jsxs("li", { ...props, children: [_jsx(Checkbox, { icon: _jsx(CheckBoxOutlineBlankIcon, { fontSize: "small" }), checkedIcon: _jsx(CheckBoxIcon, { fontSize: "small" }), style: { marginRight: 8 }, checked: selected }), option] }, key)), renderValue = (value, getTagProps) => value.map((option, index) => {
18
18
  const { key, ...rest } = getTagProps({ index });
19
19
  return _jsx(Chip, { variant: "outlined", label: option, ...rest }, key);
20
20
  }), noOptionsText = noOptions, loadingText = loadingLabel, openText = openDefault, loadData, maxItems = 16, disableCloseOnSelect = true, openOnFocus = true, label, inputProps, onChange, value, ...rest } = props;
@@ -48,7 +48,7 @@ export function TagList(props) {
48
48
  }
49
49
  }, onClose: () => {
50
50
  setOpen(false);
51
- }, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, clearOnBlur: true, openOnFocus: openOnFocus, renderOption: renderOption, renderTags: renderTags, renderInput: (params) => (_jsx(InputField, { label: label, changeDelay: 480, onChange: async (event) => {
51
+ }, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, clearOnBlur: true, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => (_jsx(InputField, { label: label, onChangeDelay: async (event) => {
52
52
  // Stop bubble
53
53
  event.preventDefault();
54
54
  event.stopPropagation();
@@ -13,7 +13,7 @@ export type TagListProProps<D extends ListType2 = ListType2> = Omit<Autocomplete
13
13
  /**
14
14
  * Input props
15
15
  */
16
- inputProps?: Omit<InputFieldProps, "onChange">;
16
+ inputProps?: Omit<InputFieldProps, "onChangeDelay">;
17
17
  /**
18
18
  * Max items
19
19
  */
@@ -50,7 +50,7 @@ export function TagListPro(props) {
50
50
  }
51
51
  }, onClose: () => {
52
52
  setOpen(false);
53
- }, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => (_jsx(InputField, { label: label, changeDelay: 480, onChange: async (event) => {
53
+ }, options: options, loading: loading, disableCloseOnSelect: disableCloseOnSelect, openOnFocus: openOnFocus, renderOption: renderOption, renderValue: renderValue, renderInput: (params) => (_jsx(InputField, { label: label, onChangeDelay: async (event) => {
54
54
  // Stop bubble
55
55
  event.preventDefault();
56
56
  event.stopPropagation();
@@ -71,8 +71,12 @@ export function Tiplist(props) {
71
71
  }
72
72
  // Stop bubble
73
73
  event.stopPropagation();
74
+ const value = event.currentTarget.value;
75
+ if (minChars && minChars > 0 && value.length < minChars) {
76
+ return;
77
+ }
74
78
  // Call with delay
75
- delayed.call(undefined, event.currentTarget.value);
79
+ delayed.call(undefined, value);
76
80
  };
77
81
  // Directly load data
78
82
  const loadDataDirect = (keyword, id) => {
@@ -191,7 +195,7 @@ export function Tiplist(props) {
191
195
  open: false,
192
196
  ...(!states.value && { options: [] })
193
197
  });
194
- }, loading: states.loading, renderInput: (params) => search ? (_jsx(SearchField, { onChange: changeHandle, ...addReadOnly(params), readOnly: readOnly, label: label, name: name + "Input", margin: inputMargin, minChars: minChars, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })) : (_jsx(InputField, { onChange: changeHandle, ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, minChars: minChars, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })), isOptionEqualToValue: (option, value) => option[idField] === value[idField], sx: sx, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionDisabled: (item) => {
198
+ }, loading: states.loading, renderInput: (params) => search ? (_jsx(SearchField, { onChange: changeHandle, ...addReadOnly(params), readOnly: readOnly, label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })) : (_jsx(InputField, { onChange: changeHandle, ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, autoComplete: inputAutoComplete, error: inputError, helperText: inputHelperText })), isOptionEqualToValue: (option, value) => option[idField] === value[idField], sx: sx, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionDisabled: (item) => {
195
199
  if (item[idField] === "n/a")
196
200
  return true;
197
201
  return getOptionDisabled ? getOptionDisabled(item) : false;
@@ -60,8 +60,12 @@ export function TiplistPro(props) {
60
60
  }
61
61
  // Stop bubble
62
62
  event.stopPropagation();
63
+ const value = event.currentTarget.value;
64
+ if (minChars && minChars > 0 && value.length < minChars) {
65
+ return;
66
+ }
63
67
  // Call with delay
64
- delayed.call(undefined, event.currentTarget.value);
68
+ delayed.call(undefined, value);
65
69
  };
66
70
  // Directly load data
67
71
  const loadDataDirect = (keyword, id) => {
@@ -183,7 +187,7 @@ export function TiplistPro(props) {
183
187
  open: false,
184
188
  ...(!states.value && { options: [] })
185
189
  });
186
- }, loading: states.loading, renderInput: (params) => (_jsx(InputField, { minChars: minChars, ...inputProps, ...params, onChange: changeHandle, label: label, name: name + "Input", onBlur: (event) => {
190
+ }, loading: states.loading, renderInput: (params) => (_jsx(InputField, { ...inputProps, ...params, onChange: changeHandle, label: label, name: name + "Input", onBlur: (event) => {
187
191
  if (states.value == null && onChange)
188
192
  onChange(event, event.target.value, "blur", undefined);
189
193
  }, "data-reset": inputReset })), isOptionEqualToValue: (option, value) => option.id === value.id, sx: sx, noOptionsText: noOptionsText, loadingText: loadingText, openText: openText, getOptionKey: getOptionKey, getOptionDisabled: (item) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.5.98",
3
+ "version": "1.5.99",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -8,12 +8,12 @@ import TextField, { TextFieldProps } from "@mui/material/TextField";
8
8
  */
9
9
  export type InputFieldProps = TextFieldProps & {
10
10
  /**
11
- * Change delay (ms) to avoid repeatly dispatch onChange
11
+ * Change [delay (ms), Minimum characters] to avoid repeatly dispatch
12
12
  */
13
- changeDelay?: number;
13
+ changeDelay?: [number, number?];
14
14
 
15
15
  /**
16
- * Change delay handler, without it onChange will be applied
16
+ * Change delay handler
17
17
  */
18
18
  onChangeDelay?: React.ChangeEventHandler<
19
19
  HTMLTextAreaElement | HTMLInputElement
@@ -23,11 +23,6 @@ export type InputFieldProps = TextFieldProps & {
23
23
  * Is the field read only?
24
24
  */
25
25
  readOnly?: boolean;
26
-
27
- /**
28
- * Minimum characters to trigger the change event
29
- */
30
- minChars?: number;
31
26
  };
32
27
 
33
28
  /**
@@ -41,13 +36,12 @@ export function InputField(props: InputFieldProps) {
41
36
  InputProps = {},
42
37
  inputProps = {},
43
38
  slotProps,
44
- changeDelay,
45
39
  onChange,
46
40
  onChangeDelay,
41
+ changeDelay = onChangeDelay ? [480] : undefined,
47
42
  readOnly,
48
43
  size = MUGlobal.inputFieldSize,
49
44
  variant = MUGlobal.inputFieldVariant,
50
- minChars = 0,
51
45
  ...rest
52
46
  } = props;
53
47
 
@@ -56,9 +50,8 @@ export function InputField(props: InputFieldProps) {
56
50
 
57
51
  const isMounted = React.useRef(true);
58
52
  const createDelayed = () => {
59
- if (changeDelay != null && changeDelay >= 1) {
60
- const changeHandler = onChangeDelay ?? onChange;
61
- if (changeHandler) return useDelayedExecutor(changeHandler, changeDelay);
53
+ if (onChangeDelay && changeDelay && changeDelay[0] >= 1) {
54
+ return useDelayedExecutor(onChangeDelay, changeDelay[0]);
62
55
  }
63
56
  return undefined;
64
57
  };
@@ -67,17 +60,19 @@ export function InputField(props: InputFieldProps) {
67
60
  const onChangeEx = (
68
61
  event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
69
62
  ) => {
70
- // Min characters check
71
- const len = event.target.value.length;
72
- if (len > 0 && len < minChars) {
73
- // Avoid to trigger the form change event
74
- event.stopPropagation();
75
- event.preventDefault();
76
- return;
77
- }
63
+ // Change handler
64
+ onChange?.(event);
78
65
 
79
- if (onChange && (delayed == null || onChangeDelay != null)) onChange(event);
80
- delayed?.call(undefined, event);
66
+ if (onChangeDelay && changeDelay && delayed) {
67
+ const [_, minChars = 0] = changeDelay;
68
+
69
+ if (minChars > 0) {
70
+ const len = event.target.value.length;
71
+ if (len < minChars) return;
72
+ }
73
+
74
+ delayed.call(undefined, event);
75
+ }
81
76
  };
82
77
 
83
78
  React.useEffect(() => {
@@ -92,7 +87,7 @@ export function InputField(props: InputFieldProps) {
92
87
  <TextField
93
88
  slotProps={{
94
89
  htmlInput: {
95
- ["data-min-chars"]: minChars,
90
+ ["data-min-chars"]: changeDelay?.[1],
96
91
  ...htmlInput,
97
92
  ...inputProps
98
93
  },
@@ -96,7 +96,7 @@ export function InputTipField<T extends ItemType = ItemType>(
96
96
  const {
97
97
  component = "input",
98
98
  componentProps,
99
- changeDelay = 480,
99
+ changeDelay,
100
100
  onChangeDelay,
101
101
  fullWidth = true,
102
102
  slotProps = {},
@@ -87,7 +87,7 @@ export function IntInputField(props: IntInputFieldProps) {
87
87
  endSymbol,
88
88
  symbol,
89
89
  value,
90
- changeDelay = 600,
90
+ changeDelay = [600],
91
91
  onChangeDelay,
92
92
  onChange,
93
93
  onFocus = (event) => event.currentTarget.select(),
package/src/QuickList.tsx CHANGED
@@ -118,11 +118,11 @@ export function QuickList<T extends ListType2 = ListType2>(
118
118
  <VBox gap={gap} height={height} {...rest}>
119
119
  <InputField
120
120
  label={label}
121
- changeDelay={480}
122
121
  onChangeDelay={(event) => {
123
122
  // Stop bubble
124
123
  event.preventDefault();
125
124
  event.stopPropagation();
125
+
126
126
  loadDataLocal(event.target.value);
127
127
  }}
128
128
  fullWidth
package/src/TagList.tsx CHANGED
@@ -27,7 +27,7 @@ export type TagListProps = Omit<
27
27
  /**
28
28
  * Input props
29
29
  */
30
- inputProps?: Omit<InputFieldProps, "onChange">;
30
+ inputProps?: Omit<InputFieldProps, "onChangeDelay">;
31
31
 
32
32
  /**
33
33
  * Max items
@@ -62,7 +62,7 @@ export function TagList(props: TagListProps) {
62
62
  {option}
63
63
  </li>
64
64
  ),
65
- renderTags = (value: readonly string[], getTagProps) =>
65
+ renderValue = (value: readonly string[], getTagProps) =>
66
66
  value.map((option, index) => {
67
67
  const { key, ...rest } = getTagProps({ index });
68
68
  return <Chip variant="outlined" key={key} label={option} {...rest} />;
@@ -129,12 +129,11 @@ export function TagList(props: TagListProps) {
129
129
  clearOnBlur
130
130
  openOnFocus={openOnFocus}
131
131
  renderOption={renderOption}
132
- renderTags={renderTags}
132
+ renderValue={renderValue}
133
133
  renderInput={(params) => (
134
134
  <InputField
135
135
  label={label}
136
- changeDelay={480}
137
- onChange={async (event) => {
136
+ onChangeDelay={async (event) => {
138
137
  // Stop bubble
139
138
  event.preventDefault();
140
139
  event.stopPropagation();
@@ -28,7 +28,7 @@ export type TagListProProps<D extends ListType2 = ListType2> = Omit<
28
28
  /**
29
29
  * Input props
30
30
  */
31
- inputProps?: Omit<InputFieldProps, "onChange">;
31
+ inputProps?: Omit<InputFieldProps, "onChangeDelay">;
32
32
 
33
33
  /**
34
34
  * Max items
@@ -147,8 +147,7 @@ export function TagListPro<D extends ListType2 = ListType2>(
147
147
  renderInput={(params) => (
148
148
  <InputField
149
149
  label={label}
150
- changeDelay={480}
151
- onChange={async (event) => {
150
+ onChangeDelay={async (event) => {
152
151
  // Stop bubble
153
152
  event.preventDefault();
154
153
  event.stopPropagation();
package/src/Tiplist.tsx CHANGED
@@ -177,8 +177,13 @@ export function Tiplist<
177
177
  // Stop bubble
178
178
  event.stopPropagation();
179
179
 
180
+ const value = event.currentTarget.value;
181
+ if (minChars && minChars > 0 && value.length < minChars) {
182
+ return;
183
+ }
184
+
180
185
  // Call with delay
181
- delayed.call(undefined, event.currentTarget.value);
186
+ delayed.call(undefined, value);
182
187
  };
183
188
 
184
189
  // Directly load data
@@ -349,7 +354,6 @@ export function Tiplist<
349
354
  label={label}
350
355
  name={name + "Input"}
351
356
  margin={inputMargin}
352
- minChars={minChars}
353
357
  variant={inputVariant}
354
358
  required={inputRequired}
355
359
  autoComplete={inputAutoComplete}
@@ -363,7 +367,6 @@ export function Tiplist<
363
367
  label={label}
364
368
  name={name + "Input"}
365
369
  margin={inputMargin}
366
- minChars={minChars}
367
370
  variant={inputVariant}
368
371
  required={inputRequired}
369
372
  autoComplete={inputAutoComplete}
@@ -194,8 +194,13 @@ export function TiplistPro<T extends ListType2 = ListType2>(
194
194
  // Stop bubble
195
195
  event.stopPropagation();
196
196
 
197
+ const value = event.currentTarget.value;
198
+ if (minChars && minChars > 0 && value.length < minChars) {
199
+ return;
200
+ }
201
+
197
202
  // Call with delay
198
- delayed.call(undefined, event.currentTarget.value);
203
+ delayed.call(undefined, value);
199
204
  };
200
205
 
201
206
  // Directly load data
@@ -363,7 +368,6 @@ export function TiplistPro<T extends ListType2 = ListType2>(
363
368
  loading={states.loading}
364
369
  renderInput={(params) => (
365
370
  <InputField
366
- minChars={minChars}
367
371
  {...inputProps}
368
372
  {...params}
369
373
  onChange={changeHandle}