@etsoo/materialui 1.1.81 → 1.1.83

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,11 +1,48 @@
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"> & 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;
19
+ /**
20
+ * Display minus and plus buttons
21
+ */
22
+ buttons?: boolean;
23
+ /**
24
+ * End symbol
25
+ */
26
+ endSymbol?: string;
27
+ /**
28
+ * Start (Currency) symbol
29
+ */
30
+ symbol?: string;
31
+ /**
32
+ * Value
33
+ */
34
+ value?: number;
35
+ /**
36
+ * Input field style
37
+ */
38
+ inputStyle?: React.CSSProperties;
39
+ /**
40
+ * On value change callback
41
+ * @param value Value
42
+ */
43
+ onValueChange?: (value: number | undefined, init: boolean) => void;
44
+ };
8
45
  /**
9
46
  * Integer input field
10
47
  */
11
- export declare const IntInputField: React.ForwardRefExoticComponent<Omit<Omit<InputFieldProps, "type" | "inputProps"> & import("@mui/material").InputBaseComponentProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
48
+ export declare const IntInputField: React.ForwardRefExoticComponent<Omit<IntInputFieldProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -1,3 +1,6 @@
1
+ import { Box, IconButton, InputAdornment } from "@mui/material";
2
+ import AddIcon from "@mui/icons-material/Add";
3
+ import RemoveIcon from "@mui/icons-material/Remove";
1
4
  import React from "react";
2
5
  import { InputField } from "./InputField";
3
6
  /**
@@ -5,7 +8,82 @@ import { InputField } from "./InputField";
5
8
  */
6
9
  export const IntInputField = React.forwardRef((props, ref) => {
7
10
  // Destruct
8
- const { min = 0, step = 1, max = 9999999, ...rest } = props;
11
+ const { min = 0, step = 1, max = 9999999, inputStyle = { textAlign: "right" }, buttons, endSymbol, symbol, value, defaultValue, onChange, onValueChange, ...rest } = props;
12
+ // State
13
+ const [localValue, setLocalValue] = React.useState();
14
+ const setValue = (value, init = false) => {
15
+ setLocalValue(value);
16
+ if (onValueChange)
17
+ onValueChange(value, init);
18
+ };
19
+ React.useEffect(() => {
20
+ setValue(value, true);
21
+ }, [value]);
22
+ React.useEffect(() => {
23
+ if (defaultValue == null)
24
+ return;
25
+ const value = typeof defaultValue === "number"
26
+ ? defaultValue
27
+ : parseFloat(`${defaultValue}`);
28
+ if (!isNaN(value))
29
+ setValue(value, true);
30
+ }, [defaultValue]);
9
31
  // Layout
10
- return (React.createElement(InputField, { ref: ref, type: "number", inputProps: { min, step, max, inputMode: "numeric" }, ...rest }));
32
+ const layout = (React.createElement(InputField, { ref: ref, type: "number", value: localValue == null ? "" : localValue, inputProps: {
33
+ min,
34
+ step,
35
+ max,
36
+ style: inputStyle,
37
+ inputMode: "numeric"
38
+ }, InputProps: {
39
+ startAdornment: symbol ? (React.createElement(React.Fragment, null,
40
+ React.createElement(InputAdornment, { position: "start" }, symbol))) : undefined,
41
+ endAdornment: endSymbol ? (React.createElement(InputAdornment, { position: "end" }, endSymbol)) : undefined
42
+ }, sx: {
43
+ "& input[type=number]::-webkit-inner-spin-button": {
44
+ WebkitAppearance: "none",
45
+ margin: 0
46
+ },
47
+ "& input[type=number]::-webkit-outer-spin-button": {
48
+ WebkitAppearance: "none",
49
+ margin: 0
50
+ }
51
+ }, onChange: (event) => {
52
+ const value = parseFloat(event.target.value);
53
+ if (isNaN(value))
54
+ setValue(undefined);
55
+ else if (value > max)
56
+ setValue(max);
57
+ else if (value < min)
58
+ setValue(min);
59
+ else
60
+ setValue(value);
61
+ if (onChange)
62
+ onChange(event);
63
+ }, ...rest }));
64
+ if (buttons)
65
+ return (React.createElement(Box, { sx: { display: "flex", alignItems: "flex-end", gap: 0.5 } },
66
+ React.createElement(IconButton, { size: "small", onClick: () => {
67
+ if (localValue == null)
68
+ return;
69
+ if (localValue <= min)
70
+ setValue(undefined);
71
+ else
72
+ setValue(localValue - step);
73
+ } },
74
+ React.createElement(RemoveIcon, null)),
75
+ layout,
76
+ React.createElement(IconButton, { size: "small", onClick: () => {
77
+ if (localValue == null) {
78
+ setValue(min);
79
+ return;
80
+ }
81
+ if (localValue >= max)
82
+ return;
83
+ else
84
+ setValue(localValue + step);
85
+ } },
86
+ React.createElement(AddIcon, { color: localValue == null ? undefined : "primary" }))));
87
+ else
88
+ return layout;
11
89
  });
@@ -1,11 +1,10 @@
1
- import { InputBaseProps } from "@mui/material";
2
1
  import React from "react";
3
- import { InputFieldProps } from "./InputField";
2
+ import { IntInputFieldProps } from "./IntInputField";
4
3
  /**
5
4
  * Money input field props
6
5
  */
7
- export type MoneyInputFieldProps = Omit<InputFieldProps, "type" | "inputProps"> & InputBaseProps["inputProps"];
6
+ export type MoneyInputFieldProps = IntInputFieldProps & {};
8
7
  /**
9
8
  * Money input field
10
9
  */
11
- export declare const MoneyInputField: React.ForwardRefExoticComponent<Omit<Omit<InputFieldProps, "type" | "inputProps"> & import("@mui/material").InputBaseComponentProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
10
+ export declare const MoneyInputField: React.ForwardRefExoticComponent<Omit<MoneyInputFieldProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
@@ -1,11 +1,11 @@
1
1
  import React from "react";
2
- import { InputField } from "./InputField";
2
+ import { IntInputField } from "./IntInputField";
3
3
  /**
4
4
  * Money input field
5
5
  */
6
6
  export const MoneyInputField = React.forwardRef((props, ref) => {
7
7
  // Destruct
8
- const { min = 0, step = 0.01, max = 9999999, ...rest } = props;
8
+ const { step = 0.01, ...rest } = props;
9
9
  // Layout
10
- return (React.createElement(InputField, { ref: ref, type: "number", inputProps: { min, step, max, inputMode: "numeric" }, ...rest }));
10
+ return React.createElement(IntInputField, { ref: ref, step: step, ...rest });
11
11
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.1.81",
3
+ "version": "1.1.83",
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.3.86",
54
54
  "@etsoo/notificationbase": "^1.1.24",
55
55
  "@etsoo/react": "^1.6.57",
56
- "@etsoo/shared": "^1.1.94",
56
+ "@etsoo/shared": "^1.1.95",
57
57
  "@mui/icons-material": "^5.11.11",
58
58
  "@mui/material": "^5.11.15",
59
- "@mui/x-data-grid": "^6.0.3",
59
+ "@mui/x-data-grid": "^6.0.4",
60
60
  "@types/pica": "^9.0.1",
61
61
  "@types/pulltorefreshjs": "^0.1.5",
62
62
  "@types/react": "^18.0.31",
@@ -89,6 +89,6 @@
89
89
  "@typescript-eslint/parser": "^5.57.0",
90
90
  "jest": "^29.5.0",
91
91
  "jest-environment-jsdom": "^29.5.0",
92
- "typescript": "^5.0.2"
92
+ "typescript": "^5.0.3"
93
93
  }
94
94
  }
@@ -1,12 +1,62 @@
1
- import { InputBaseProps } from "@mui/material";
1
+ import { Box, IconButton, InputAdornment } from "@mui/material";
2
+ import AddIcon from "@mui/icons-material/Add";
3
+ import RemoveIcon from "@mui/icons-material/Remove";
2
4
  import React from "react";
3
5
  import { InputField, InputFieldProps } from "./InputField";
4
6
 
5
7
  /**
6
8
  * Integer input field props
7
9
  */
8
- export type IntInputFieldProps = Omit<InputFieldProps, "type" | "inputProps"> &
9
- InputBaseProps["inputProps"];
10
+ export type IntInputFieldProps = Omit<
11
+ InputFieldProps,
12
+ "type" | "inputProps" | "value"
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
+ */
58
+ onValueChange?: (value: number | undefined, init: boolean) => void;
59
+ };
10
60
 
11
61
  /**
12
62
  * Integer input field
@@ -16,15 +66,115 @@ export const IntInputField = React.forwardRef<
16
66
  IntInputFieldProps
17
67
  >((props, ref) => {
18
68
  // Destruct
19
- const { min = 0, step = 1, max = 9999999, ...rest } = props;
69
+ const {
70
+ min = 0,
71
+ step = 1,
72
+ max = 9999999,
73
+ inputStyle = { textAlign: "right" },
74
+ buttons,
75
+ endSymbol,
76
+ symbol,
77
+ value,
78
+ defaultValue,
79
+ onChange,
80
+ onValueChange,
81
+ ...rest
82
+ } = props;
83
+
84
+ // State
85
+ const [localValue, setLocalValue] = React.useState<number>();
86
+
87
+ const setValue = (value: number | undefined, init: boolean = false) => {
88
+ setLocalValue(value);
89
+ if (onValueChange) onValueChange(value, init);
90
+ };
91
+
92
+ React.useEffect(() => {
93
+ setValue(value, true);
94
+ }, [value]);
95
+
96
+ React.useEffect(() => {
97
+ if (defaultValue == null) return;
98
+ const value =
99
+ typeof defaultValue === "number"
100
+ ? defaultValue
101
+ : parseFloat(`${defaultValue}`);
102
+ if (!isNaN(value)) setValue(value, true);
103
+ }, [defaultValue]);
20
104
 
21
105
  // Layout
22
- return (
106
+ const layout = (
23
107
  <InputField
24
108
  ref={ref}
25
109
  type="number"
26
- inputProps={{ min, step, max, inputMode: "numeric" }}
110
+ value={localValue == null ? "" : localValue}
111
+ inputProps={{
112
+ min,
113
+ step,
114
+ max,
115
+ style: inputStyle,
116
+ inputMode: "numeric"
117
+ }}
118
+ InputProps={{
119
+ startAdornment: symbol ? (
120
+ <React.Fragment>
121
+ <InputAdornment position="start">{symbol}</InputAdornment>
122
+ </React.Fragment>
123
+ ) : undefined,
124
+ endAdornment: endSymbol ? (
125
+ <InputAdornment position="end">{endSymbol}</InputAdornment>
126
+ ) : undefined
127
+ }}
128
+ sx={{
129
+ "& input[type=number]::-webkit-inner-spin-button": {
130
+ WebkitAppearance: "none",
131
+ margin: 0
132
+ },
133
+ "& input[type=number]::-webkit-outer-spin-button": {
134
+ WebkitAppearance: "none",
135
+ margin: 0
136
+ }
137
+ }}
138
+ onChange={(event) => {
139
+ const value = parseFloat(event.target.value);
140
+ if (isNaN(value)) setValue(undefined);
141
+ else if (value > max) setValue(max);
142
+ else if (value < min) setValue(min);
143
+ else setValue(value);
144
+ if (onChange) onChange(event);
145
+ }}
27
146
  {...rest}
28
147
  />
29
148
  );
149
+
150
+ if (buttons)
151
+ return (
152
+ <Box sx={{ display: "flex", alignItems: "flex-end", gap: 0.5 }}>
153
+ <IconButton
154
+ size="small"
155
+ onClick={() => {
156
+ if (localValue == null) return;
157
+ if (localValue <= min) setValue(undefined);
158
+ else setValue(localValue - step);
159
+ }}
160
+ >
161
+ <RemoveIcon />
162
+ </IconButton>
163
+ {layout}
164
+ <IconButton
165
+ size="small"
166
+ onClick={() => {
167
+ if (localValue == null) {
168
+ setValue(min);
169
+ return;
170
+ }
171
+ if (localValue >= max) return;
172
+ else setValue(localValue + step);
173
+ }}
174
+ >
175
+ <AddIcon color={localValue == null ? undefined : "primary"} />
176
+ </IconButton>
177
+ </Box>
178
+ );
179
+ else return layout;
30
180
  });
@@ -1,15 +1,10 @@
1
- import { InputBaseProps } from "@mui/material";
2
1
  import React from "react";
3
- import { InputField, InputFieldProps } from "./InputField";
2
+ import { IntInputField, IntInputFieldProps } from "./IntInputField";
4
3
 
5
4
  /**
6
5
  * Money input field props
7
6
  */
8
- export type MoneyInputFieldProps = Omit<
9
- InputFieldProps,
10
- "type" | "inputProps"
11
- > &
12
- InputBaseProps["inputProps"];
7
+ export type MoneyInputFieldProps = IntInputFieldProps & {};
13
8
 
14
9
  /**
15
10
  * Money input field
@@ -19,15 +14,8 @@ export const MoneyInputField = React.forwardRef<
19
14
  MoneyInputFieldProps
20
15
  >((props, ref) => {
21
16
  // Destruct
22
- const { min = 0, step = 0.01, max = 9999999, ...rest } = props;
17
+ const { step = 0.01, ...rest } = props;
23
18
 
24
19
  // Layout
25
- return (
26
- <InputField
27
- ref={ref}
28
- type="number"
29
- inputProps={{ min, step, max, inputMode: "numeric" }}
30
- {...rest}
31
- />
32
- );
20
+ return <IntInputField ref={ref} step={step} {...rest} />;
33
21
  });