@etsoo/materialui 1.3.68 → 1.3.69
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.
- package/lib/UserAvatarEditor.js +13 -5
- package/package.json +4 -4
- package/src/UserAvatarEditor.tsx +20 -7
package/lib/UserAvatarEditor.js
CHANGED
|
@@ -10,6 +10,7 @@ import RemoveIcon from "@mui/icons-material/Remove";
|
|
|
10
10
|
import AddIcon from "@mui/icons-material/Add";
|
|
11
11
|
import { Labels } from "./app/Labels";
|
|
12
12
|
import { FileUploadButton } from "./FileUploadButton";
|
|
13
|
+
const defaultSize = 300;
|
|
13
14
|
const defaultState = {
|
|
14
15
|
scale: 1,
|
|
15
16
|
rotate: 0
|
|
@@ -22,11 +23,11 @@ const defaultState = {
|
|
|
22
23
|
*/
|
|
23
24
|
export function UserAvatarEditor(props) {
|
|
24
25
|
// Destruct
|
|
25
|
-
const { border = 30, image, maxWidth, onDone, scaledResult = false, width =
|
|
26
|
+
const { border = 30, image, maxWidth, onDone, scaledResult = false, width = defaultSize, height = defaultSize, range = [0.1, 2, 0.1] } = props;
|
|
26
27
|
// Container width
|
|
27
28
|
const containerWidth = width + 2 * border + 44 + 4;
|
|
28
29
|
// Calculated max width
|
|
29
|
-
const maxWidthCalculated = maxWidth == null || maxWidth <
|
|
30
|
+
const maxWidthCalculated = maxWidth == null || maxWidth < defaultSize ? 2 * width : maxWidth;
|
|
30
31
|
// Labels
|
|
31
32
|
const labels = Labels.UserAvatarEditor;
|
|
32
33
|
// Ref
|
|
@@ -41,6 +42,10 @@ export function UserAvatarEditor(props) {
|
|
|
41
42
|
const [ready, setReady] = React.useState(false);
|
|
42
43
|
// Editor states
|
|
43
44
|
const [editorState, setEditorState] = React.useState(defaultState);
|
|
45
|
+
// Height
|
|
46
|
+
// noHeight: height is not set and will be updated dynamically
|
|
47
|
+
const noHeight = height <= 0;
|
|
48
|
+
const [localHeight, setHeight] = React.useState(noHeight ? defaultSize : height);
|
|
44
49
|
// Range
|
|
45
50
|
const [min, max, step] = range;
|
|
46
51
|
const marks = [
|
|
@@ -69,7 +74,10 @@ export function UserAvatarEditor(props) {
|
|
|
69
74
|
setScale(editorState.scale + (isAdd ? step : -step));
|
|
70
75
|
};
|
|
71
76
|
// Handle image load
|
|
72
|
-
const handleLoad = () => {
|
|
77
|
+
const handleLoad = (imageInfo) => {
|
|
78
|
+
if (noHeight) {
|
|
79
|
+
setHeight((imageInfo.height * width) / imageInfo.width);
|
|
80
|
+
}
|
|
73
81
|
setReady(true);
|
|
74
82
|
};
|
|
75
83
|
// Handle file upload
|
|
@@ -115,7 +123,7 @@ export function UserAvatarEditor(props) {
|
|
|
115
123
|
};
|
|
116
124
|
if (data.width > maxWidthCalculated) {
|
|
117
125
|
// Target height
|
|
118
|
-
const heightCalculated = (
|
|
126
|
+
const heightCalculated = (localHeight * maxWidthCalculated) / width;
|
|
119
127
|
// Target
|
|
120
128
|
const to = document.createElement("canvas");
|
|
121
129
|
to.width = maxWidthCalculated;
|
|
@@ -136,5 +144,5 @@ export function UserAvatarEditor(props) {
|
|
|
136
144
|
};
|
|
137
145
|
// Load the component
|
|
138
146
|
const AE = React.lazy(() => import("react-avatar-editor"));
|
|
139
|
-
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:
|
|
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 })] }));
|
|
140
148
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.69",
|
|
4
4
|
"description": "TypeScript Material-UI Implementation",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"@etsoo/notificationbase": "^1.1.42",
|
|
55
55
|
"@etsoo/react": "^1.7.54",
|
|
56
56
|
"@etsoo/shared": "^1.2.41",
|
|
57
|
-
"@mui/icons-material": "^5.15.
|
|
58
|
-
"@mui/material": "^5.15.
|
|
59
|
-
"@mui/x-data-grid": "^7.
|
|
57
|
+
"@mui/icons-material": "^5.15.19",
|
|
58
|
+
"@mui/material": "^5.15.19",
|
|
59
|
+
"@mui/x-data-grid": "^7.6.1",
|
|
60
60
|
"chart.js": "^4.4.3",
|
|
61
61
|
"chartjs-plugin-datalabels": "^2.2.0",
|
|
62
62
|
"eventemitter3": "^5.0.1",
|
package/src/UserAvatarEditor.tsx
CHANGED
|
@@ -17,6 +17,9 @@ import RemoveIcon from "@mui/icons-material/Remove";
|
|
|
17
17
|
import AddIcon from "@mui/icons-material/Add";
|
|
18
18
|
import { Labels } from "./app/Labels";
|
|
19
19
|
import { FileUploadButton } from "./FileUploadButton";
|
|
20
|
+
import { ImageState } from "react-avatar-editor";
|
|
21
|
+
|
|
22
|
+
const defaultSize = 300;
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
25
|
* User avatar editor to Blob helper
|
|
@@ -109,8 +112,8 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
|
|
|
109
112
|
maxWidth,
|
|
110
113
|
onDone,
|
|
111
114
|
scaledResult = false,
|
|
112
|
-
width =
|
|
113
|
-
height =
|
|
115
|
+
width = defaultSize,
|
|
116
|
+
height = defaultSize,
|
|
114
117
|
range = [0.1, 2, 0.1]
|
|
115
118
|
} = props;
|
|
116
119
|
|
|
@@ -119,7 +122,7 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
|
|
|
119
122
|
|
|
120
123
|
// Calculated max width
|
|
121
124
|
const maxWidthCalculated =
|
|
122
|
-
maxWidth == null || maxWidth <
|
|
125
|
+
maxWidth == null || maxWidth < defaultSize ? 2 * width : maxWidth;
|
|
123
126
|
|
|
124
127
|
// Labels
|
|
125
128
|
const labels = Labels.UserAvatarEditor;
|
|
@@ -142,6 +145,13 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
|
|
|
142
145
|
// Editor states
|
|
143
146
|
const [editorState, setEditorState] = React.useState(defaultState);
|
|
144
147
|
|
|
148
|
+
// Height
|
|
149
|
+
// noHeight: height is not set and will be updated dynamically
|
|
150
|
+
const noHeight = height <= 0;
|
|
151
|
+
const [localHeight, setHeight] = React.useState(
|
|
152
|
+
noHeight ? defaultSize : height
|
|
153
|
+
);
|
|
154
|
+
|
|
145
155
|
// Range
|
|
146
156
|
const [min, max, step] = range;
|
|
147
157
|
const marks = [
|
|
@@ -179,7 +189,10 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
|
|
|
179
189
|
};
|
|
180
190
|
|
|
181
191
|
// Handle image load
|
|
182
|
-
const handleLoad = () => {
|
|
192
|
+
const handleLoad = (imageInfo: ImageState) => {
|
|
193
|
+
if (noHeight) {
|
|
194
|
+
setHeight((imageInfo.height * width) / imageInfo.width);
|
|
195
|
+
}
|
|
183
196
|
setReady(true);
|
|
184
197
|
};
|
|
185
198
|
|
|
@@ -238,7 +251,7 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
|
|
|
238
251
|
|
|
239
252
|
if (data.width > maxWidthCalculated) {
|
|
240
253
|
// Target height
|
|
241
|
-
const heightCalculated = (
|
|
254
|
+
const heightCalculated = (localHeight * maxWidthCalculated) / width;
|
|
242
255
|
|
|
243
256
|
// Target
|
|
244
257
|
const to = document.createElement("canvas");
|
|
@@ -277,14 +290,14 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
|
|
|
277
290
|
<Stack direction="row" spacing={0.5}>
|
|
278
291
|
<React.Suspense
|
|
279
292
|
fallback={
|
|
280
|
-
<Skeleton variant="rounded" width={width} height={
|
|
293
|
+
<Skeleton variant="rounded" width={width} height={localHeight} />
|
|
281
294
|
}
|
|
282
295
|
>
|
|
283
296
|
<AE
|
|
284
297
|
ref={ref}
|
|
285
298
|
border={border}
|
|
286
299
|
width={width}
|
|
287
|
-
height={
|
|
300
|
+
height={localHeight}
|
|
288
301
|
onLoadSuccess={handleLoad}
|
|
289
302
|
image={previewImage ?? ""}
|
|
290
303
|
scale={editorState.scale}
|