@etsoo/materialui 1.0.38 → 1.0.40

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.
@@ -0,0 +1,39 @@
1
+ /// <reference types="react" />
2
+ import { TextFieldProps } from '@mui/material';
3
+ import { InputDialogProps } from '@etsoo/react';
4
+ /**
5
+ * Data step
6
+ */
7
+ export declare type DataStep = Omit<InputDialogProps, 'callback'> & {
8
+ /**
9
+ * Callback
10
+ */
11
+ callback: (form: HTMLFormElement) => boolean | void;
12
+ };
13
+ /**
14
+ * Data collecting steps component props
15
+ */
16
+ export declare type DataStepsProps<T extends object> = Omit<TextFieldProps, 'InputProps' | 'onClick'> & {
17
+ /**
18
+ * JSON value
19
+ */
20
+ jsonValue?: string;
21
+ /**
22
+ * Value formatter
23
+ */
24
+ valueFormatter?: (data: T) => string;
25
+ /**
26
+ * Steps
27
+ */
28
+ steps: (index: number, data: T) => [DataStep, boolean];
29
+ /**
30
+ * On value change handler
31
+ */
32
+ onValueChange?: (value: T) => void;
33
+ };
34
+ /**
35
+ * Data collecting steps component
36
+ * @param props Props
37
+ * @returns Component
38
+ */
39
+ export declare function DataSteps<T extends object>(props: DataStepsProps<T>): JSX.Element;
@@ -0,0 +1,84 @@
1
+ import { Button, IconButton, InputAdornment, TextField } from '@mui/material';
2
+ import CloseIcon from '@mui/icons-material/Close';
3
+ import NavigateNextIcon from '@mui/icons-material/NavigateNext';
4
+ import NavigateBeforeIcon from '@mui/icons-material/NavigateBefore';
5
+ import CheckIcon from '@mui/icons-material/Check';
6
+ import StartIcon from '@mui/icons-material/Start';
7
+ import React from 'react';
8
+ import { globalApp } from './app/ReactApp';
9
+ import { MUGlobal } from './MUGlobal';
10
+ import { HBox } from './FlexBox';
11
+ /**
12
+ * Data collecting steps component
13
+ * @param props Props
14
+ * @returns Component
15
+ */
16
+ export function DataSteps(props) {
17
+ var _a;
18
+ // App
19
+ const app = globalApp;
20
+ // Labels
21
+ const labels = app.getLabels('close', 'nextStep', 'previousStep', 'submit');
22
+ // Destruct
23
+ const { InputLabelProps = {}, jsonValue, valueFormatter = (_data) => '...', onValueChange, steps, value = '', ...rest } = props;
24
+ // Shrink
25
+ (_a = InputLabelProps.shrink) !== null && _a !== void 0 ? _a : (InputLabelProps.shrink = MUGlobal.searchFieldShrink);
26
+ // Current index
27
+ const indexRef = React.useRef(-1);
28
+ // Current data
29
+ const dataRef = React.useRef({});
30
+ // Current value
31
+ const [localValue, setLocalValue] = React.useState(value);
32
+ // Get step
33
+ const showStep = (index) => {
34
+ indexRef.current = index;
35
+ const [{ callback, ...rest }, more] = steps(index, dataRef.current);
36
+ app.showInputDialog({
37
+ ...rest,
38
+ buttons: (n, callback) => (React.createElement(HBox, { paddingLeft: 2, paddingRight: 2, paddingBottom: 2, gap: 2, justifyContent: "space-between" },
39
+ index === 0 ? (React.createElement(Button, { variant: "outlined", startIcon: React.createElement(CloseIcon, null), onClick: () => n.dismiss() }, labels.close)) : (React.createElement(Button, { variant: "outlined", startIcon: React.createElement(NavigateBeforeIcon, null), onClick: () => {
40
+ n.dismiss();
41
+ showStep(indexRef.current - 1);
42
+ } }, labels.previousStep)),
43
+ more ? (React.createElement(Button, { variant: "contained", startIcon: React.createElement(NavigateNextIcon, null), onClick: async (event) => {
44
+ const result = await callback(event);
45
+ if (!result)
46
+ return;
47
+ showStep(indexRef.current + 1);
48
+ } }, labels.nextStep)) : (React.createElement(Button, { variant: "contained", startIcon: React.createElement(CheckIcon, null), onClick: async (event) => {
49
+ const result = await callback(event);
50
+ if (!result)
51
+ return;
52
+ const value = dataRef.current;
53
+ setLocalValue(valueFormatter(value));
54
+ if (onValueChange)
55
+ onValueChange(value);
56
+ } }, labels.submit)))),
57
+ callback: (form) => {
58
+ if (form == null)
59
+ return;
60
+ const result = callback(form);
61
+ if (result !== true) {
62
+ return false;
63
+ }
64
+ }
65
+ });
66
+ };
67
+ const cancelInput = (event) => {
68
+ event.stopPropagation();
69
+ event.preventDefault();
70
+ };
71
+ React.useEffect(() => {
72
+ if (jsonValue) {
73
+ dataRef.current = JSON.parse(jsonValue);
74
+ setLocalValue(valueFormatter(dataRef.current));
75
+ }
76
+ }, [jsonValue]);
77
+ return (React.createElement(TextField, { InputLabelProps: InputLabelProps, InputProps: {
78
+ onKeyDown: cancelInput,
79
+ onPaste: cancelInput,
80
+ endAdornment: (React.createElement(InputAdornment, { position: "end" },
81
+ React.createElement(IconButton, { edge: "end", size: "small" },
82
+ React.createElement(StartIcon, null))))
83
+ }, sx: { cursor: 'pointer' }, onClick: () => showStep(0), value: localValue, ...rest }));
84
+ }
package/lib/InputField.js CHANGED
@@ -8,10 +8,11 @@ import { MUGlobal } from './MUGlobal';
8
8
  * @returns Component
9
9
  */
10
10
  export function InputField(props) {
11
+ var _a;
11
12
  // Destruct
12
13
  const { changeDelay, InputLabelProps = {}, InputProps = {}, onChange, readOnly, size = MUGlobal.inputFieldSize, variant = MUGlobal.inputFieldVariant, ...rest } = props;
13
14
  // Shrink
14
- InputLabelProps.shrink = MUGlobal.searchFieldShrink;
15
+ (_a = InputLabelProps.shrink) !== null && _a !== void 0 ? _a : (InputLabelProps.shrink = MUGlobal.searchFieldShrink);
15
16
  // Read only
16
17
  if (readOnly != null)
17
18
  InputProps.readOnly = readOnly;
package/lib/MaskInput.js CHANGED
@@ -9,6 +9,7 @@ import { useIMask } from 'react-imask';
9
9
  * @returns Component
10
10
  */
11
11
  export function MaskInput(props) {
12
+ var _a;
12
13
  // Destruct
13
14
  const { defaultValue, mask, InputLabelProps = {}, InputProps = {}, onAccept, onComplete, readOnly, search = false, size = search ? MUGlobal.searchFieldSize : MUGlobal.inputFieldSize, value, variant = search
14
15
  ? MUGlobal.searchFieldVariant
@@ -25,9 +26,9 @@ export function MaskInput(props) {
25
26
  });
26
27
  const localValue = defaultValue !== null && defaultValue !== void 0 ? defaultValue : value;
27
28
  // Shrink
28
- InputLabelProps.shrink = search
29
+ (_a = InputLabelProps.shrink) !== null && _a !== void 0 ? _a : (InputLabelProps.shrink = search
29
30
  ? MUGlobal.searchFieldShrink
30
- : MUGlobal.inputFieldShrink;
31
+ : MUGlobal.inputFieldShrink);
31
32
  // Read only
32
33
  if (readOnly != null)
33
34
  InputProps.readOnly = readOnly;
@@ -8,10 +8,11 @@ import { MUGlobal } from './MUGlobal';
8
8
  * @returns Component
9
9
  */
10
10
  export function SearchField(props) {
11
+ var _a;
11
12
  // Destruct
12
13
  const { changeDelay, InputLabelProps = {}, InputProps = {}, onChange, readOnly, size = MUGlobal.searchFieldSize, variant = MUGlobal.searchFieldVariant, ...rest } = props;
13
14
  // Shrink
14
- InputLabelProps.shrink = MUGlobal.searchFieldShrink;
15
+ (_a = InputLabelProps.shrink) !== null && _a !== void 0 ? _a : (InputLabelProps.shrink = MUGlobal.searchFieldShrink);
15
16
  // Read only
16
17
  if (readOnly != null)
17
18
  InputProps.readOnly = readOnly;
package/lib/index.d.ts CHANGED
@@ -31,6 +31,7 @@ export * from './CountdownButton';
31
31
  export * from './CustomFabProps';
32
32
  export * from './DataGridEx';
33
33
  export * from './DataGridRenderers';
34
+ export * from './DataSteps';
34
35
  export * from './DialogButton';
35
36
  export * from './DnDList';
36
37
  export * from './DraggablePaperComponent';
package/lib/index.js CHANGED
@@ -31,6 +31,7 @@ export * from './CountdownButton';
31
31
  export * from './CustomFabProps';
32
32
  export * from './DataGridEx';
33
33
  export * from './DataGridRenderers';
34
+ export * from './DataSteps';
34
35
  export * from './DialogButton';
35
36
  export * from './DnDList';
36
37
  export * from './DraggablePaperComponent';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.0.38",
3
+ "version": "1.0.40",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -51,10 +51,10 @@
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.3.0",
55
- "@etsoo/notificationbase": "^1.1.11",
56
- "@etsoo/react": "^1.6.11",
57
- "@etsoo/shared": "^1.1.58",
54
+ "@etsoo/appscript": "^1.3.1",
55
+ "@etsoo/notificationbase": "^1.1.12",
56
+ "@etsoo/react": "^1.6.12",
57
+ "@etsoo/shared": "^1.1.59",
58
58
  "@mui/icons-material": "^5.10.6",
59
59
  "@mui/material": "^5.10.7",
60
60
  "@types/pica": "^9.0.1",
@@ -82,16 +82,16 @@
82
82
  "@babel/runtime-corejs3": "^7.19.1",
83
83
  "@testing-library/jest-dom": "^5.16.5",
84
84
  "@testing-library/react": "^13.4.0",
85
- "@types/jest": "^29.0.3",
85
+ "@types/jest": "^29.1.1",
86
86
  "@typescript-eslint/eslint-plugin": "^5.38.1",
87
87
  "@typescript-eslint/parser": "^5.38.1",
88
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
- "jest": "^29.0.3",
93
- "jest-environment-jsdom": "^29.0.3",
94
- "ts-jest": "^29.0.2",
92
+ "jest": "^29.1.2",
93
+ "jest-environment-jsdom": "^29.1.2",
94
+ "ts-jest": "^29.0.3",
95
95
  "typescript": "^4.8.4"
96
96
  }
97
97
  }
@@ -0,0 +1,201 @@
1
+ import {
2
+ Button,
3
+ IconButton,
4
+ InputAdornment,
5
+ TextField,
6
+ TextFieldProps
7
+ } from '@mui/material';
8
+ import CloseIcon from '@mui/icons-material/Close';
9
+ import NavigateNextIcon from '@mui/icons-material/NavigateNext';
10
+ import NavigateBeforeIcon from '@mui/icons-material/NavigateBefore';
11
+ import CheckIcon from '@mui/icons-material/Check';
12
+ import StartIcon from '@mui/icons-material/Start';
13
+ import { InputDialogProps } from '@etsoo/react';
14
+ import React from 'react';
15
+ import { globalApp } from './app/ReactApp';
16
+ import { MUGlobal } from './MUGlobal';
17
+ import { HBox } from './FlexBox';
18
+
19
+ /**
20
+ * Data step
21
+ */
22
+ export type DataStep = Omit<InputDialogProps, 'callback'> & {
23
+ /**
24
+ * Callback
25
+ */
26
+ callback: (form: HTMLFormElement) => boolean | void;
27
+ };
28
+
29
+ /**
30
+ * Data collecting steps component props
31
+ */
32
+ export type DataStepsProps<T extends object> = Omit<
33
+ TextFieldProps,
34
+ 'InputProps' | 'onClick'
35
+ > & {
36
+ /**
37
+ * JSON value
38
+ */
39
+ jsonValue?: string;
40
+
41
+ /**
42
+ * Value formatter
43
+ */
44
+ valueFormatter?: (data: T) => string;
45
+
46
+ /**
47
+ * Steps
48
+ */
49
+ steps: (index: number, data: T) => [DataStep, boolean];
50
+
51
+ /**
52
+ * On value change handler
53
+ */
54
+ onValueChange?: (value: T) => void;
55
+ };
56
+
57
+ /**
58
+ * Data collecting steps component
59
+ * @param props Props
60
+ * @returns Component
61
+ */
62
+ export function DataSteps<T extends object>(props: DataStepsProps<T>) {
63
+ // App
64
+ const app = globalApp;
65
+
66
+ // Labels
67
+ const labels = app.getLabels('close', 'nextStep', 'previousStep', 'submit');
68
+
69
+ // Destruct
70
+ const {
71
+ InputLabelProps = {},
72
+ jsonValue,
73
+ valueFormatter = (_data: T) => '...',
74
+ onValueChange,
75
+ steps,
76
+ value = '',
77
+ ...rest
78
+ } = props;
79
+
80
+ // Shrink
81
+ InputLabelProps.shrink ??= MUGlobal.searchFieldShrink;
82
+
83
+ // Current index
84
+ const indexRef = React.useRef<number>(-1);
85
+
86
+ // Current data
87
+ const dataRef = React.useRef({} as T);
88
+
89
+ // Current value
90
+ const [localValue, setLocalValue] = React.useState(value);
91
+
92
+ // Get step
93
+ const showStep = (index: number) => {
94
+ indexRef.current = index;
95
+ const [{ callback, ...rest }, more] = steps(index, dataRef.current);
96
+
97
+ app.showInputDialog({
98
+ ...rest,
99
+ buttons: (n, callback) => (
100
+ <HBox
101
+ paddingLeft={2}
102
+ paddingRight={2}
103
+ paddingBottom={2}
104
+ gap={2}
105
+ justifyContent="space-between"
106
+ >
107
+ {index === 0 ? (
108
+ <Button
109
+ variant="outlined"
110
+ startIcon={<CloseIcon />}
111
+ onClick={() => n.dismiss()}
112
+ >
113
+ {labels.close}
114
+ </Button>
115
+ ) : (
116
+ <Button
117
+ variant="outlined"
118
+ startIcon={<NavigateBeforeIcon />}
119
+ onClick={() => {
120
+ n.dismiss();
121
+ showStep(indexRef.current - 1);
122
+ }}
123
+ >
124
+ {labels.previousStep}
125
+ </Button>
126
+ )}
127
+
128
+ {more ? (
129
+ <Button
130
+ variant="contained"
131
+ startIcon={<NavigateNextIcon />}
132
+ onClick={async (event) => {
133
+ const result = await callback(event);
134
+ if (!result) return;
135
+ showStep(indexRef.current + 1);
136
+ }}
137
+ >
138
+ {labels.nextStep}
139
+ </Button>
140
+ ) : (
141
+ <Button
142
+ variant="contained"
143
+ startIcon={<CheckIcon />}
144
+ onClick={async (event) => {
145
+ const result = await callback(event);
146
+ if (!result) return;
147
+
148
+ const value = dataRef.current;
149
+ setLocalValue(valueFormatter(value));
150
+
151
+ if (onValueChange) onValueChange(value);
152
+ }}
153
+ >
154
+ {labels.submit}
155
+ </Button>
156
+ )}
157
+ </HBox>
158
+ ),
159
+ callback: (form) => {
160
+ if (form == null) return;
161
+ const result = callback(form);
162
+ if (result !== true) {
163
+ return false;
164
+ }
165
+ }
166
+ });
167
+ };
168
+
169
+ const cancelInput = (event: React.SyntheticEvent) => {
170
+ event.stopPropagation();
171
+ event.preventDefault();
172
+ };
173
+
174
+ React.useEffect(() => {
175
+ if (jsonValue) {
176
+ dataRef.current = JSON.parse(jsonValue);
177
+ setLocalValue(valueFormatter(dataRef.current));
178
+ }
179
+ }, [jsonValue]);
180
+
181
+ return (
182
+ <TextField
183
+ InputLabelProps={InputLabelProps}
184
+ InputProps={{
185
+ onKeyDown: cancelInput,
186
+ onPaste: cancelInput,
187
+ endAdornment: (
188
+ <InputAdornment position="end">
189
+ <IconButton edge="end" size="small">
190
+ <StartIcon />
191
+ </IconButton>
192
+ </InputAdornment>
193
+ )
194
+ }}
195
+ sx={{ cursor: 'pointer' }}
196
+ onClick={() => showStep(0)}
197
+ value={localValue}
198
+ {...rest}
199
+ />
200
+ );
201
+ }
@@ -37,7 +37,7 @@ export function InputField(props: InputFieldProps) {
37
37
  } = props;
38
38
 
39
39
  // Shrink
40
- InputLabelProps.shrink = MUGlobal.searchFieldShrink;
40
+ InputLabelProps.shrink ??= MUGlobal.searchFieldShrink;
41
41
 
42
42
  // Read only
43
43
  if (readOnly != null) InputProps.readOnly = readOnly;
package/src/MaskInput.tsx CHANGED
@@ -80,7 +80,7 @@ export function MaskInput<
80
80
  const localValue = defaultValue ?? value;
81
81
 
82
82
  // Shrink
83
- InputLabelProps.shrink = search
83
+ InputLabelProps.shrink ??= search
84
84
  ? MUGlobal.searchFieldShrink
85
85
  : MUGlobal.inputFieldShrink;
86
86
 
@@ -37,7 +37,7 @@ export function SearchField(props: SearchFieldProps) {
37
37
  } = props;
38
38
 
39
39
  // Shrink
40
- InputLabelProps.shrink = MUGlobal.searchFieldShrink;
40
+ InputLabelProps.shrink ??= MUGlobal.searchFieldShrink;
41
41
 
42
42
  // Read only
43
43
  if (readOnly != null) InputProps.readOnly = readOnly;
package/src/index.ts CHANGED
@@ -34,6 +34,7 @@ export * from './CountdownButton';
34
34
  export * from './CustomFabProps';
35
35
  export * from './DataGridEx';
36
36
  export * from './DataGridRenderers';
37
+ export * from './DataSteps';
37
38
  export * from './DialogButton';
38
39
  export * from './DnDList';
39
40
  export * from './DraggablePaperComponent';