@etsoo/materialui 1.4.27 → 1.4.29

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.
@@ -8,7 +8,7 @@ export interface UserAvatarEditorToBlob {
8
8
  * User avatar editor on done handler
9
9
  */
10
10
  export interface UserAvatarEditorOnDoneHandler {
11
- (canvas: HTMLCanvasElement, toBlob: UserAvatarEditorToBlob, type: string): void;
11
+ (canvas: HTMLCanvasElement, toBlob: UserAvatarEditorToBlob, type: string): void | false;
12
12
  }
13
13
  /**
14
14
  * User avatar editor props
@@ -30,6 +30,10 @@ export interface UserAvatarEditorProps {
30
30
  * On done handler
31
31
  */
32
32
  onDone: UserAvatarEditorOnDoneHandler;
33
+ /**
34
+ * Select file label
35
+ */
36
+ selectFileLabel?: string;
33
37
  /**
34
38
  * Return scaled result?
35
39
  */
@@ -4,7 +4,7 @@ import React from "react";
4
4
  import RotateLeftIcon from "@mui/icons-material/RotateLeft";
5
5
  import RotateRightIcon from "@mui/icons-material/RotateRight";
6
6
  import ClearAllIcon from "@mui/icons-material/ClearAll";
7
- import ComputerIcon from "@mui/icons-material/Computer";
7
+ import ImageIcon from "@mui/icons-material/Image";
8
8
  import DoneIcon from "@mui/icons-material/Done";
9
9
  import RemoveIcon from "@mui/icons-material/Remove";
10
10
  import AddIcon from "@mui/icons-material/Add";
@@ -22,14 +22,14 @@ const defaultState = {
22
22
  * @returns Component
23
23
  */
24
24
  export function UserAvatarEditor(props) {
25
+ // Labels
26
+ const labels = Labels.UserAvatarEditor;
25
27
  // Destruct
26
- const { border = 30, image, maxWidth, onDone, scaledResult = false, width = defaultSize, height = defaultSize, range = [0.1, 2, 0.1] } = props;
28
+ const { border = 30, image, maxWidth, onDone, scaledResult = false, width = defaultSize, height = defaultSize, range = [0.1, 2, 0.1], selectFileLabel = labels.selectFile + "..." } = props;
27
29
  // Container width
28
30
  const containerWidth = width + 2 * border + 44 + 4;
29
31
  // Calculated max width
30
32
  const maxWidthCalculated = maxWidth == null || maxWidth < defaultSize ? 2 * width : maxWidth;
31
- // Labels
32
- const labels = Labels.UserAvatarEditor;
33
33
  // Ref
34
34
  const ref = React.createRef();
35
35
  // Image type
@@ -97,6 +97,10 @@ export function UserAvatarEditor(props) {
97
97
  const handleReset = () => {
98
98
  setEditorState({ ...defaultState });
99
99
  };
100
+ const resetUI = () => {
101
+ setPreviewImage(undefined);
102
+ handleReset();
103
+ };
100
104
  // Handle rotate
101
105
  const handleRotate = (r) => {
102
106
  let rotate = editorState.rotate + r;
@@ -136,13 +140,17 @@ export function UserAvatarEditor(props) {
136
140
  unsharpRadius: 0.6,
137
141
  unsharpThreshold: 1
138
142
  })
139
- .then((result) => onDone(result, toBlob, type.current));
143
+ .then((result) => {
144
+ if (onDone(result, toBlob, type.current) === false) {
145
+ resetUI();
146
+ }
147
+ });
140
148
  }
141
- else {
142
- onDone(data, toBlob, type.current);
149
+ else if (onDone(data, toBlob, type.current) === false) {
150
+ resetUI();
143
151
  }
144
152
  };
145
153
  // Load the component
146
154
  const AE = React.lazy(() => import("react-avatar-editor"));
147
- return (_jsxs(Stack, { direction: "column", spacing: 0.5, width: containerWidth, children: [_jsx(FileUploadButton, { variant: "outlined", size: "medium", startIcon: _jsx(ComputerIcon, {}), fullWidth: true, onUploadFiles: handleFileUpload, inputProps: { multiple: false, accept: "image/png, image/jpeg" }, children: labels.upload }), _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(React.Suspense, { fallback: _jsx(Skeleton, { variant: "rounded", width: width, height: localHeight }), children: _jsx(AE, { ref: ref, border: border, width: width, height: localHeight, onLoadSuccess: handleLoad, image: previewImage ?? "", scale: editorState.scale, rotate: editorState.rotate }) }), _jsxs(ButtonGroup, { size: "small", orientation: "vertical", disabled: !ready, children: [_jsx(Button, { onClick: () => handleRotate(90), title: labels.rotateRight, children: _jsx(RotateRightIcon, {}) }), _jsx(Button, { onClick: () => handleRotate(-90), title: labels.rotateLeft, children: _jsx(RotateLeftIcon, {}) }), _jsx(Button, { onClick: handleReset, title: labels.reset, children: _jsx(ClearAllIcon, {}) })] })] }), _jsxs(Stack, { spacing: 0.5, direction: "row", sx: { paddingBottom: 2 }, alignItems: "center", children: [_jsx(IconButton, { size: "small", disabled: !ready || editorState.scale <= min, onClick: () => adjustScale(false), children: _jsx(RemoveIcon, {}) }), _jsx(Slider, { title: labels.zoom, disabled: !ready, min: min, max: max, step: step, value: editorState.scale, valueLabelDisplay: "auto", valueLabelFormat: (value) => `${Math.round(100 * value) / 100}`, marks: marks, onChange: handleZoom }), _jsx(IconButton, { size: "small", disabled: !ready || editorState.scale >= max, onClick: () => adjustScale(true), children: _jsx(AddIcon, {}) })] }), _jsx(Button, { ref: buttonRef, variant: "contained", startIcon: _jsx(DoneIcon, {}), disabled: !ready, onClick: handleDone, children: labels.done })] }));
155
+ return (_jsxs(Stack, { direction: "column", spacing: 0.5, width: containerWidth, children: [_jsx(FileUploadButton, { variant: "outlined", size: "medium", startIcon: _jsx(ImageIcon, {}), fullWidth: true, onUploadFiles: handleFileUpload, inputProps: { multiple: false, accept: "image/png, image/jpeg" }, children: selectFileLabel }), _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(React.Suspense, { fallback: _jsx(Skeleton, { variant: "rounded", width: width, height: localHeight }), children: _jsx(AE, { ref: ref, border: border, width: width, height: localHeight, onLoadSuccess: handleLoad, image: previewImage ?? "", scale: editorState.scale, rotate: editorState.rotate }) }), _jsxs(ButtonGroup, { size: "small", orientation: "vertical", disabled: !ready, children: [_jsx(Button, { onClick: () => handleRotate(90), title: labels.rotateRight, children: _jsx(RotateRightIcon, {}) }), _jsx(Button, { onClick: () => handleRotate(-90), title: labels.rotateLeft, children: _jsx(RotateLeftIcon, {}) }), _jsx(Button, { onClick: handleReset, title: labels.reset, children: _jsx(ClearAllIcon, {}) })] })] }), _jsxs(Stack, { spacing: 0.5, direction: "row", sx: { paddingBottom: 2 }, alignItems: "center", children: [_jsx(IconButton, { size: "small", disabled: !ready || editorState.scale <= min, onClick: () => adjustScale(false), children: _jsx(RemoveIcon, {}) }), _jsx(Slider, { title: labels.zoom, disabled: !ready, min: min, max: max, step: step, value: editorState.scale, valueLabelDisplay: "auto", valueLabelFormat: (value) => `${Math.round(100 * value) / 100}`, marks: marks, onChange: handleZoom }), _jsx(IconButton, { size: "small", disabled: !ready || editorState.scale >= max, onClick: () => adjustScale(true), children: _jsx(AddIcon, {}) })] }), _jsx(Button, { ref: buttonRef, variant: "contained", startIcon: _jsx(DoneIcon, {}), disabled: !ready, onClick: handleDone, children: labels.done })] }));
148
156
  }
@@ -45,7 +45,7 @@ export declare namespace Labels {
45
45
  reset: string;
46
46
  rotateLeft: string;
47
47
  rotateRight: string;
48
- upload: string;
48
+ selectFile: string;
49
49
  zoom: string;
50
50
  };
51
51
  /**
package/lib/app/Labels.js CHANGED
@@ -46,7 +46,7 @@ export var Labels;
46
46
  reset: "Reset",
47
47
  rotateLeft: "Rotate left 90°",
48
48
  rotateRight: "Rotate right 90°",
49
- upload: "Upload",
49
+ selectFile: "Select file",
50
50
  zoom: "Zoom"
51
51
  };
52
52
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.4.27",
3
+ "version": "1.4.29",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -35,12 +35,12 @@
35
35
  "@emotion/css": "^11.13.5",
36
36
  "@emotion/react": "^11.13.5",
37
37
  "@emotion/styled": "^11.13.5",
38
- "@etsoo/appscript": "^1.5.69",
38
+ "@etsoo/appscript": "^1.5.71",
39
39
  "@etsoo/notificationbase": "^1.1.54",
40
40
  "@etsoo/react": "^1.8.3",
41
41
  "@etsoo/shared": "^1.2.55",
42
- "@mui/icons-material": "^6.1.8",
43
- "@mui/material": "^6.1.8",
42
+ "@mui/icons-material": "^6.1.9",
43
+ "@mui/material": "^6.1.9",
44
44
  "@mui/x-data-grid": "^7.22.3",
45
45
  "chart.js": "^4.4.6",
46
46
  "chartjs-plugin-datalabels": "^2.2.0",
@@ -11,7 +11,7 @@ import type AvatarEditor from "react-avatar-editor";
11
11
  import RotateLeftIcon from "@mui/icons-material/RotateLeft";
12
12
  import RotateRightIcon from "@mui/icons-material/RotateRight";
13
13
  import ClearAllIcon from "@mui/icons-material/ClearAll";
14
- import ComputerIcon from "@mui/icons-material/Computer";
14
+ import ImageIcon from "@mui/icons-material/Image";
15
15
  import DoneIcon from "@mui/icons-material/Done";
16
16
  import RemoveIcon from "@mui/icons-material/Remove";
17
17
  import AddIcon from "@mui/icons-material/Add";
@@ -36,11 +36,9 @@ export interface UserAvatarEditorToBlob {
36
36
  * User avatar editor on done handler
37
37
  */
38
38
  export interface UserAvatarEditorOnDoneHandler {
39
- (
40
- canvas: HTMLCanvasElement,
41
- toBlob: UserAvatarEditorToBlob,
42
- type: string
43
- ): void;
39
+ (canvas: HTMLCanvasElement, toBlob: UserAvatarEditorToBlob, type: string):
40
+ | void
41
+ | false;
44
42
  }
45
43
 
46
44
  /**
@@ -67,6 +65,11 @@ export interface UserAvatarEditorProps {
67
65
  */
68
66
  onDone: UserAvatarEditorOnDoneHandler;
69
67
 
68
+ /**
69
+ * Select file label
70
+ */
71
+ selectFileLabel?: string;
72
+
70
73
  /**
71
74
  * Return scaled result?
72
75
  */
@@ -105,6 +108,9 @@ const defaultState: EditorState = {
105
108
  * @returns Component
106
109
  */
107
110
  export function UserAvatarEditor(props: UserAvatarEditorProps) {
111
+ // Labels
112
+ const labels = Labels.UserAvatarEditor;
113
+
108
114
  // Destruct
109
115
  const {
110
116
  border = 30,
@@ -114,7 +120,8 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
114
120
  scaledResult = false,
115
121
  width = defaultSize,
116
122
  height = defaultSize,
117
- range = [0.1, 2, 0.1]
123
+ range = [0.1, 2, 0.1],
124
+ selectFileLabel = labels.selectFile + "..."
118
125
  } = props;
119
126
 
120
127
  // Container width
@@ -124,9 +131,6 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
124
131
  const maxWidthCalculated =
125
132
  maxWidth == null || maxWidth < defaultSize ? 2 * width : maxWidth;
126
133
 
127
- // Labels
128
- const labels = Labels.UserAvatarEditor;
129
-
130
134
  // Ref
131
135
  const ref = React.createRef<AvatarEditor>();
132
136
 
@@ -218,6 +222,11 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
218
222
  setEditorState({ ...defaultState });
219
223
  };
220
224
 
225
+ const resetUI = () => {
226
+ setPreviewImage(undefined);
227
+ handleReset();
228
+ };
229
+
221
230
  // Handle rotate
222
231
  const handleRotate = (r: number) => {
223
232
  let rotate = editorState.rotate + r;
@@ -266,9 +275,13 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
266
275
  unsharpRadius: 0.6,
267
276
  unsharpThreshold: 1
268
277
  })
269
- .then((result) => onDone(result, toBlob, type.current));
270
- } else {
271
- onDone(data, toBlob, type.current);
278
+ .then((result) => {
279
+ if (onDone(result, toBlob, type.current) === false) {
280
+ resetUI();
281
+ }
282
+ });
283
+ } else if (onDone(data, toBlob, type.current) === false) {
284
+ resetUI();
272
285
  }
273
286
  };
274
287
 
@@ -280,12 +293,12 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
280
293
  <FileUploadButton
281
294
  variant="outlined"
282
295
  size="medium"
283
- startIcon={<ComputerIcon />}
296
+ startIcon={<ImageIcon />}
284
297
  fullWidth
285
298
  onUploadFiles={handleFileUpload}
286
299
  inputProps={{ multiple: false, accept: "image/png, image/jpeg" }}
287
300
  >
288
- {labels.upload}
301
+ {selectFileLabel}
289
302
  </FileUploadButton>
290
303
  <Stack direction="row" spacing={0.5}>
291
304
  <React.Suspense
package/src/app/Labels.ts CHANGED
@@ -48,7 +48,7 @@ export namespace Labels {
48
48
  reset: "Reset",
49
49
  rotateLeft: "Rotate left 90°",
50
50
  rotateRight: "Rotate right 90°",
51
- upload: "Upload",
51
+ selectFile: "Select file",
52
52
  zoom: "Zoom"
53
53
  };
54
54