@etsoo/materialui 1.1.82 → 1.1.84

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.
@@ -1,10 +1,21 @@
1
- import { InputBaseProps } from "@mui/material";
2
1
  import React from "react";
3
2
  import { InputFieldProps } from "./InputField";
4
3
  /**
5
4
  * Integer input field props
6
5
  */
7
- export type IntInputFieldProps = Omit<InputFieldProps, "type" | "inputProps" | "value"> & InputBaseProps["inputProps"] & {
6
+ export type IntInputFieldProps = Omit<InputFieldProps, "type" | "inputProps" | "value"> & {
7
+ /**
8
+ * Minimum value
9
+ */
10
+ min?: number;
11
+ /**
12
+ * Maximum value
13
+ */
14
+ max?: number;
15
+ /**
16
+ * Step value
17
+ */
18
+ step?: number;
8
19
  /**
9
20
  * Display minus and plus buttons
10
21
  */
@@ -21,35 +32,19 @@ export type IntInputFieldProps = Omit<InputFieldProps, "type" | "inputProps" | "
21
32
  * Value
22
33
  */
23
34
  value?: number;
35
+ /**
36
+ * Input field style
37
+ */
38
+ inputStyle?: React.CSSProperties;
24
39
  /**
25
40
  * On value change callback
26
41
  * @param value Value
42
+ * @param source Source value
43
+ * @param init Initial action
27
44
  */
28
- onValueChange?: (value: number | undefined, init: boolean) => void;
45
+ onValueChange?: (value: number | undefined, source: unknown, init: boolean) => number | undefined;
29
46
  };
30
47
  /**
31
48
  * Integer input field
32
49
  */
33
- export declare const IntInputField: React.ForwardRefExoticComponent<Omit<Omit<InputFieldProps, "type" | "value" | "inputProps"> & import("@mui/material").InputBaseComponentProps & {
34
- /**
35
- * Display minus and plus buttons
36
- */
37
- buttons?: boolean | undefined;
38
- /**
39
- * End symbol
40
- */
41
- endSymbol?: string | undefined;
42
- /**
43
- * Start (Currency) symbol
44
- */
45
- symbol?: string | undefined;
46
- /**
47
- * Value
48
- */
49
- value?: number | undefined;
50
- /**
51
- * On value change callback
52
- * @param value Value
53
- */
54
- onValueChange?: ((value: number | undefined, init: boolean) => void) | undefined;
55
- }, "ref"> & React.RefAttributes<HTMLDivElement>>;
50
+ export declare const IntInputField: React.ForwardRefExoticComponent<Omit<IntInputFieldProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -8,32 +8,33 @@ import { InputField } from "./InputField";
8
8
  */
9
9
  export const IntInputField = React.forwardRef((props, ref) => {
10
10
  // Destruct
11
- const { min = 0, step = 1, max = 9999999, style = { textAlign: "right" }, buttons, endSymbol, symbol, value, defaultValue, onChange, onValueChange, ...rest } = props;
11
+ const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, buttons, endSymbol, symbol, value, defaultValue, onChangeDelay, onValueChange, required, ...rest } = props;
12
12
  // State
13
13
  const [localValue, setLocalValue] = React.useState();
14
- const setValue = (value, init = false) => {
15
- setLocalValue(value);
16
- if (onValueChange)
17
- onValueChange(value, init);
14
+ const setValue = (value, source, init = false) => {
15
+ if (onValueChange) {
16
+ const newValue = onValueChange(value, source, init);
17
+ setLocalValue(newValue);
18
+ }
18
19
  };
19
20
  React.useEffect(() => {
20
- setValue(value, true);
21
+ setValue(value, undefined, true);
21
22
  }, [value]);
22
23
  React.useEffect(() => {
23
- if (defaultValue == null || typeof defaultValue === "object")
24
+ if (defaultValue == null)
24
25
  return;
25
26
  const value = typeof defaultValue === "number"
26
27
  ? defaultValue
27
- : parseFloat(defaultValue);
28
+ : parseFloat(`${defaultValue}`);
28
29
  if (!isNaN(value))
29
- setValue(value, true);
30
+ setValue(value, defaultValue, true);
30
31
  }, [defaultValue]);
31
32
  // Layout
32
- const layout = (React.createElement(InputField, { ref: ref, type: "number", value: localValue == null ? "" : localValue, inputProps: {
33
+ const layout = (React.createElement(InputField, { ref: ref, type: "number", value: localValue == null ? (required ? min : "") : localValue, inputProps: {
33
34
  min,
34
35
  step,
35
36
  max,
36
- style,
37
+ style: inputStyle,
37
38
  inputMode: "numeric"
38
39
  }, InputProps: {
39
40
  startAdornment: symbol ? (React.createElement(React.Fragment, null,
@@ -48,18 +49,20 @@ export const IntInputField = React.forwardRef((props, ref) => {
48
49
  WebkitAppearance: "none",
49
50
  margin: 0
50
51
  }
51
- }, onChange: (event) => {
52
- const value = parseFloat(event.target.value);
52
+ }, onChangeDelay: (event) => {
53
+ const source = event.target.value;
54
+ const value = parseFloat(source);
53
55
  if (isNaN(value))
54
- setValue(undefined);
56
+ setValue(undefined, source);
55
57
  else if (value > max)
56
- setValue(max);
58
+ setValue(max, source);
57
59
  else if (value < min)
58
- setValue(min);
60
+ setValue(value === 0 ? undefined : min, source);
61
+ // 0 is a special case
59
62
  else
60
- setValue(value);
61
- if (onChange)
62
- onChange(event);
63
+ setValue(value, source);
64
+ if (onChangeDelay)
65
+ onChangeDelay(event);
63
66
  }, ...rest }));
64
67
  if (buttons)
65
68
  return (React.createElement(Box, { sx: { display: "flex", alignItems: "flex-end", gap: 0.5 } },
@@ -67,21 +70,21 @@ export const IntInputField = React.forwardRef((props, ref) => {
67
70
  if (localValue == null)
68
71
  return;
69
72
  if (localValue <= min)
70
- setValue(undefined);
73
+ setValue(undefined, "SUB");
71
74
  else
72
- setValue(localValue - step);
75
+ setValue(localValue - step, "SUB");
73
76
  } },
74
77
  React.createElement(RemoveIcon, null)),
75
78
  layout,
76
79
  React.createElement(IconButton, { size: "small", onClick: () => {
77
80
  if (localValue == null) {
78
- setValue(min);
81
+ setValue(min, "ADD");
79
82
  return;
80
83
  }
81
84
  if (localValue >= max)
82
85
  return;
83
86
  else
84
- setValue(localValue + step);
87
+ setValue(localValue + step, "ADD");
85
88
  } },
86
89
  React.createElement(AddIcon, { color: localValue == null ? undefined : "primary" }))));
87
90
  else
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.1.82",
3
+ "version": "1.1.84",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { Box, IconButton, InputAdornment, InputBaseProps } from "@mui/material";
1
+ import { Box, IconButton, InputAdornment } from "@mui/material";
2
2
  import AddIcon from "@mui/icons-material/Add";
3
3
  import RemoveIcon from "@mui/icons-material/Remove";
4
4
  import React from "react";
@@ -10,34 +10,59 @@ import { InputField, InputFieldProps } from "./InputField";
10
10
  export type IntInputFieldProps = Omit<
11
11
  InputFieldProps,
12
12
  "type" | "inputProps" | "value"
13
- > &
14
- InputBaseProps["inputProps"] & {
15
- /**
16
- * Display minus and plus buttons
17
- */
18
- buttons?: boolean;
19
-
20
- /**
21
- * End symbol
22
- */
23
- endSymbol?: string;
24
-
25
- /**
26
- * Start (Currency) symbol
27
- */
28
- symbol?: string;
29
-
30
- /**
31
- * Value
32
- */
33
- value?: number;
34
-
35
- /**
36
- * On value change callback
37
- * @param value Value
38
- */
39
- onValueChange?: (value: number | undefined, init: boolean) => void;
40
- };
13
+ > & {
14
+ /**
15
+ * Minimum value
16
+ */
17
+ min?: number;
18
+
19
+ /**
20
+ * Maximum value
21
+ */
22
+ max?: number;
23
+
24
+ /**
25
+ * Step value
26
+ */
27
+ step?: number;
28
+
29
+ /**
30
+ * Display minus and plus buttons
31
+ */
32
+ buttons?: boolean;
33
+
34
+ /**
35
+ * End symbol
36
+ */
37
+ endSymbol?: string;
38
+
39
+ /**
40
+ * Start (Currency) symbol
41
+ */
42
+ symbol?: string;
43
+
44
+ /**
45
+ * Value
46
+ */
47
+ value?: number;
48
+
49
+ /**
50
+ * Input field style
51
+ */
52
+ inputStyle?: React.CSSProperties;
53
+
54
+ /**
55
+ * On value change callback
56
+ * @param value Value
57
+ * @param source Source value
58
+ * @param init Initial action
59
+ */
60
+ onValueChange?: (
61
+ value: number | undefined,
62
+ source: unknown,
63
+ init: boolean
64
+ ) => number | undefined;
65
+ };
41
66
 
42
67
  /**
43
68
  * Integer input field
@@ -51,36 +76,43 @@ export const IntInputField = React.forwardRef<
51
76
  min = 0,
52
77
  step = 1,
53
78
  max = 9999999,
54
- style = { textAlign: "right" },
79
+ inputStyle = { textAlign: "right" },
55
80
  buttons,
56
81
  endSymbol,
57
82
  symbol,
58
83
  value,
59
84
  defaultValue,
60
- onChange,
85
+ onChangeDelay,
61
86
  onValueChange,
87
+ required,
62
88
  ...rest
63
89
  } = props;
64
90
 
65
91
  // State
66
92
  const [localValue, setLocalValue] = React.useState<number>();
67
93
 
68
- const setValue = (value: number | undefined, init: boolean = false) => {
69
- setLocalValue(value);
70
- if (onValueChange) onValueChange(value, init);
94
+ const setValue = (
95
+ value: number | undefined,
96
+ source: unknown,
97
+ init: boolean = false
98
+ ) => {
99
+ if (onValueChange) {
100
+ const newValue = onValueChange(value, source, init);
101
+ setLocalValue(newValue);
102
+ }
71
103
  };
72
104
 
73
105
  React.useEffect(() => {
74
- setValue(value, true);
106
+ setValue(value, undefined, true);
75
107
  }, [value]);
76
108
 
77
109
  React.useEffect(() => {
78
- if (defaultValue == null || typeof defaultValue === "object") return;
110
+ if (defaultValue == null) return;
79
111
  const value =
80
112
  typeof defaultValue === "number"
81
113
  ? defaultValue
82
- : parseFloat(defaultValue);
83
- if (!isNaN(value)) setValue(value, true);
114
+ : parseFloat(`${defaultValue}`);
115
+ if (!isNaN(value)) setValue(value, defaultValue, true);
84
116
  }, [defaultValue]);
85
117
 
86
118
  // Layout
@@ -88,12 +120,12 @@ export const IntInputField = React.forwardRef<
88
120
  <InputField
89
121
  ref={ref}
90
122
  type="number"
91
- value={localValue == null ? "" : localValue}
123
+ value={localValue == null ? (required ? min : "") : localValue}
92
124
  inputProps={{
93
125
  min,
94
126
  step,
95
127
  max,
96
- style,
128
+ style: inputStyle,
97
129
  inputMode: "numeric"
98
130
  }}
99
131
  InputProps={{
@@ -116,13 +148,16 @@ export const IntInputField = React.forwardRef<
116
148
  margin: 0
117
149
  }
118
150
  }}
119
- onChange={(event) => {
120
- const value = parseFloat(event.target.value);
121
- if (isNaN(value)) setValue(undefined);
122
- else if (value > max) setValue(max);
123
- else if (value < min) setValue(min);
124
- else setValue(value);
125
- if (onChange) onChange(event);
151
+ onChangeDelay={(event) => {
152
+ const source = event.target.value;
153
+ const value = parseFloat(source);
154
+ if (isNaN(value)) setValue(undefined, source);
155
+ else if (value > max) setValue(max, source);
156
+ else if (value < min) setValue(value === 0 ? undefined : min, source);
157
+ // 0 is a special case
158
+ else setValue(value, source);
159
+
160
+ if (onChangeDelay) onChangeDelay(event);
126
161
  }}
127
162
  {...rest}
128
163
  />
@@ -135,8 +170,8 @@ export const IntInputField = React.forwardRef<
135
170
  size="small"
136
171
  onClick={() => {
137
172
  if (localValue == null) return;
138
- if (localValue <= min) setValue(undefined);
139
- else setValue(localValue - step);
173
+ if (localValue <= min) setValue(undefined, "SUB");
174
+ else setValue(localValue - step, "SUB");
140
175
  }}
141
176
  >
142
177
  <RemoveIcon />
@@ -146,11 +181,11 @@ export const IntInputField = React.forwardRef<
146
181
  size="small"
147
182
  onClick={() => {
148
183
  if (localValue == null) {
149
- setValue(min);
184
+ setValue(min, "ADD");
150
185
  return;
151
186
  }
152
187
  if (localValue >= max) return;
153
- else setValue(localValue + step);
188
+ else setValue(localValue + step, "ADD");
154
189
  }}
155
190
  >
156
191
  <AddIcon color={localValue == null ? undefined : "primary"} />