@etsoo/materialui 1.2.59 → 1.2.61
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/FileUploadButton.d.ts +22 -0
- package/lib/FileUploadButton.js +27 -0
- package/lib/UserAvatarEditor.js +4 -8
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/pages/ViewPage.d.ts +1 -1
- package/lib/pages/ViewPage.js +1 -1
- package/package.json +5 -5
- package/src/FileUploadButton.tsx +55 -0
- package/src/UserAvatarEditor.tsx +7 -16
- package/src/index.ts +1 -0
- package/src/pages/ViewPage.tsx +2 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ButtonProps } from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* File upload button props
|
|
5
|
+
*/
|
|
6
|
+
export type FileUploadButtonProps = ButtonProps<"label"> & {
|
|
7
|
+
/**
|
|
8
|
+
* Input field attributes
|
|
9
|
+
*/
|
|
10
|
+
inputProps?: Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "hidden">;
|
|
11
|
+
/**
|
|
12
|
+
* Upload files callback
|
|
13
|
+
* @param files Files
|
|
14
|
+
*/
|
|
15
|
+
onUploadFiles?: (files: FileList) => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* File upload button
|
|
19
|
+
* @param props Props
|
|
20
|
+
* @returns Component
|
|
21
|
+
*/
|
|
22
|
+
export declare function FileUploadButton(props: FileUploadButtonProps): React.JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Button } from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* File upload button
|
|
5
|
+
* @param props Props
|
|
6
|
+
* @returns Component
|
|
7
|
+
*/
|
|
8
|
+
export function FileUploadButton(props) {
|
|
9
|
+
// Destruct
|
|
10
|
+
const { inputProps, onUploadFiles, children, ...rest } = props;
|
|
11
|
+
const { onChange } = inputProps !== null && inputProps !== void 0 ? inputProps : {};
|
|
12
|
+
// Layout
|
|
13
|
+
return (React.createElement(Button, { component: "label", ...rest },
|
|
14
|
+
children,
|
|
15
|
+
React.createElement("input", { type: "file", hidden: true, onChange: (event) => {
|
|
16
|
+
if (onChange)
|
|
17
|
+
onChange(event);
|
|
18
|
+
if (event.isDefaultPrevented())
|
|
19
|
+
return;
|
|
20
|
+
if (onUploadFiles) {
|
|
21
|
+
const files = event.target.files;
|
|
22
|
+
if (files == null || files.length == 0)
|
|
23
|
+
return;
|
|
24
|
+
onUploadFiles(files);
|
|
25
|
+
}
|
|
26
|
+
}, ...inputProps })));
|
|
27
|
+
}
|
package/lib/UserAvatarEditor.js
CHANGED
|
@@ -8,6 +8,7 @@ import DoneIcon from "@mui/icons-material/Done";
|
|
|
8
8
|
import RemoveIcon from "@mui/icons-material/Remove";
|
|
9
9
|
import AddIcon from "@mui/icons-material/Add";
|
|
10
10
|
import { Labels } from "./app/Labels";
|
|
11
|
+
import { FileUploadButton } from "./FileUploadButton";
|
|
11
12
|
const defaultState = {
|
|
12
13
|
scale: 1,
|
|
13
14
|
rotate: 0
|
|
@@ -70,12 +71,9 @@ export function UserAvatarEditor(props) {
|
|
|
70
71
|
const handleLoad = () => {
|
|
71
72
|
setReady(true);
|
|
72
73
|
};
|
|
73
|
-
// Handle file
|
|
74
|
-
const
|
|
74
|
+
// Handle file upload
|
|
75
|
+
const handleFileUpload = (files) => {
|
|
75
76
|
var _a;
|
|
76
|
-
const files = event.target.files;
|
|
77
|
-
if (files == null || files.length == 0)
|
|
78
|
-
return;
|
|
79
77
|
// Reset all settings
|
|
80
78
|
handleReset();
|
|
81
79
|
// Set new preview image
|
|
@@ -140,9 +138,7 @@ export function UserAvatarEditor(props) {
|
|
|
140
138
|
// Load the component
|
|
141
139
|
const AE = React.lazy(() => import("react-avatar-editor"));
|
|
142
140
|
return (React.createElement(Stack, { direction: "column", spacing: 0.5, width: containerWidth },
|
|
143
|
-
React.createElement(
|
|
144
|
-
labels.upload,
|
|
145
|
-
React.createElement("input", { id: "fileInput", type: "file", accept: "image/png, image/jpeg", multiple: false, hidden: true, onChange: handleFileChange })),
|
|
141
|
+
React.createElement(FileUploadButton, { variant: "outlined", size: "medium", startIcon: React.createElement(ComputerIcon, null), fullWidth: true, onUploadFiles: handleFileUpload, inputProps: { multiple: false, accept: "image/png, image/jpeg" } }, labels.upload),
|
|
146
142
|
React.createElement(Stack, { direction: "row", spacing: 0.5 },
|
|
147
143
|
React.createElement(React.Suspense, { fallback: React.createElement(Skeleton, { variant: "rounded", width: width, height: height }) },
|
|
148
144
|
React.createElement(AE, { ref: ref, border: border, width: width, height: height, onLoadSuccess: handleLoad, image: previewImage !== null && previewImage !== void 0 ? previewImage : "", scale: editorState.scale, rotate: editorState.rotate })),
|
package/lib/index.d.ts
CHANGED
|
@@ -47,6 +47,7 @@ export * from "./DnDList";
|
|
|
47
47
|
export * from "./DraggablePaperComponent";
|
|
48
48
|
export * from "./EmailInput";
|
|
49
49
|
export * from "./FabBox";
|
|
50
|
+
export * from "./FileUploadButton";
|
|
50
51
|
export * from "./FlexBox";
|
|
51
52
|
export * from "./GridDataFormat";
|
|
52
53
|
export * from "./HiSelector";
|
package/lib/index.js
CHANGED
|
@@ -47,6 +47,7 @@ export * from "./DnDList";
|
|
|
47
47
|
export * from "./DraggablePaperComponent";
|
|
48
48
|
export * from "./EmailInput";
|
|
49
49
|
export * from "./FabBox";
|
|
50
|
+
export * from "./FileUploadButton";
|
|
50
51
|
export * from "./FlexBox";
|
|
51
52
|
export * from "./GridDataFormat";
|
|
52
53
|
export * from "./HiSelector";
|
package/lib/pages/ViewPage.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ type ViewPageFieldTypeNarrow<T extends object> = (string & keyof T) | [string &
|
|
|
36
36
|
/**
|
|
37
37
|
* View page field type
|
|
38
38
|
*/
|
|
39
|
-
export type ViewPageFieldType<T extends object> = ViewPageFieldTypeNarrow<T> | ((data: T) => React.ReactNode);
|
|
39
|
+
export type ViewPageFieldType<T extends object> = ViewPageFieldTypeNarrow<T> | ((data: T, refresh: () => Promise<void>) => React.ReactNode);
|
|
40
40
|
/**
|
|
41
41
|
* View page props
|
|
42
42
|
*/
|
package/lib/pages/ViewPage.js
CHANGED
|
@@ -107,7 +107,7 @@ export function ViewPage(props) {
|
|
|
107
107
|
// Get data
|
|
108
108
|
if (typeof field === "function") {
|
|
109
109
|
// Most flexible way, do whatever you want
|
|
110
|
-
return field(data);
|
|
110
|
+
return field(data, refresh);
|
|
111
111
|
}
|
|
112
112
|
const [itemData, itemLabel, gridProps] = getItemField(field, data);
|
|
113
113
|
// Some callback function may return '' instead of undefined
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/materialui",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.61",
|
|
4
4
|
"description": "TypeScript Material-UI Implementation",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -47,16 +47,16 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@dnd-kit/core": "^6.0.8",
|
|
49
49
|
"@dnd-kit/sortable": "^7.0.2",
|
|
50
|
-
"@emotion/css": "^11.11.
|
|
50
|
+
"@emotion/css": "^11.11.2",
|
|
51
51
|
"@emotion/react": "^11.11.1",
|
|
52
52
|
"@emotion/styled": "^11.11.0",
|
|
53
|
-
"@etsoo/appscript": "^1.4.
|
|
53
|
+
"@etsoo/appscript": "^1.4.20",
|
|
54
54
|
"@etsoo/notificationbase": "^1.1.25",
|
|
55
55
|
"@etsoo/react": "^1.6.93",
|
|
56
|
-
"@etsoo/shared": "^1.2.
|
|
56
|
+
"@etsoo/shared": "^1.2.7",
|
|
57
57
|
"@mui/icons-material": "^5.11.16",
|
|
58
58
|
"@mui/material": "^5.13.5",
|
|
59
|
-
"@mui/x-data-grid": "^6.
|
|
59
|
+
"@mui/x-data-grid": "^6.8.0",
|
|
60
60
|
"@types/pica": "^9.0.1",
|
|
61
61
|
"@types/pulltorefreshjs": "^0.1.5",
|
|
62
62
|
"@types/react": "^18.2.12",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Button, ButtonProps } from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* File upload button props
|
|
6
|
+
*/
|
|
7
|
+
export type FileUploadButtonProps = ButtonProps<"label"> & {
|
|
8
|
+
/**
|
|
9
|
+
* Input field attributes
|
|
10
|
+
*/
|
|
11
|
+
inputProps?: Omit<
|
|
12
|
+
React.InputHTMLAttributes<HTMLInputElement>,
|
|
13
|
+
"type" | "hidden"
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Upload files callback
|
|
18
|
+
* @param files Files
|
|
19
|
+
*/
|
|
20
|
+
onUploadFiles?: (files: FileList) => void;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* File upload button
|
|
25
|
+
* @param props Props
|
|
26
|
+
* @returns Component
|
|
27
|
+
*/
|
|
28
|
+
export function FileUploadButton(props: FileUploadButtonProps) {
|
|
29
|
+
// Destruct
|
|
30
|
+
const { inputProps, onUploadFiles, children, ...rest } = props;
|
|
31
|
+
|
|
32
|
+
const { onChange } = inputProps ?? {};
|
|
33
|
+
|
|
34
|
+
// Layout
|
|
35
|
+
return (
|
|
36
|
+
<Button component="label" {...rest}>
|
|
37
|
+
{children}
|
|
38
|
+
<input
|
|
39
|
+
type="file"
|
|
40
|
+
hidden={true}
|
|
41
|
+
onChange={(event) => {
|
|
42
|
+
if (onChange) onChange(event);
|
|
43
|
+
if (event.isDefaultPrevented()) return;
|
|
44
|
+
|
|
45
|
+
if (onUploadFiles) {
|
|
46
|
+
const files = event.target.files;
|
|
47
|
+
if (files == null || files.length == 0) return;
|
|
48
|
+
onUploadFiles(files);
|
|
49
|
+
}
|
|
50
|
+
}}
|
|
51
|
+
{...inputProps}
|
|
52
|
+
/>
|
|
53
|
+
</Button>
|
|
54
|
+
);
|
|
55
|
+
}
|
package/src/UserAvatarEditor.tsx
CHANGED
|
@@ -16,6 +16,7 @@ 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";
|
|
18
18
|
import { Labels } from "./app/Labels";
|
|
19
|
+
import { FileUploadButton } from "./FileUploadButton";
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* User avatar editor to Blob helper
|
|
@@ -182,11 +183,8 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
|
|
|
182
183
|
setReady(true);
|
|
183
184
|
};
|
|
184
185
|
|
|
185
|
-
// Handle file
|
|
186
|
-
const
|
|
187
|
-
const files = event.target.files;
|
|
188
|
-
if (files == null || files.length == 0) return;
|
|
189
|
-
|
|
186
|
+
// Handle file upload
|
|
187
|
+
const handleFileUpload = (files: FileList) => {
|
|
190
188
|
// Reset all settings
|
|
191
189
|
handleReset();
|
|
192
190
|
|
|
@@ -266,23 +264,16 @@ export function UserAvatarEditor(props: UserAvatarEditorProps) {
|
|
|
266
264
|
|
|
267
265
|
return (
|
|
268
266
|
<Stack direction="column" spacing={0.5} width={containerWidth}>
|
|
269
|
-
<
|
|
267
|
+
<FileUploadButton
|
|
270
268
|
variant="outlined"
|
|
271
269
|
size="medium"
|
|
272
|
-
component="label"
|
|
273
270
|
startIcon={<ComputerIcon />}
|
|
274
271
|
fullWidth
|
|
272
|
+
onUploadFiles={handleFileUpload}
|
|
273
|
+
inputProps={{ multiple: false, accept: "image/png, image/jpeg" }}
|
|
275
274
|
>
|
|
276
275
|
{labels.upload}
|
|
277
|
-
|
|
278
|
-
id="fileInput"
|
|
279
|
-
type="file"
|
|
280
|
-
accept="image/png, image/jpeg"
|
|
281
|
-
multiple={false}
|
|
282
|
-
hidden
|
|
283
|
-
onChange={handleFileChange}
|
|
284
|
-
/>
|
|
285
|
-
</Button>
|
|
276
|
+
</FileUploadButton>
|
|
286
277
|
<Stack direction="row" spacing={0.5}>
|
|
287
278
|
<React.Suspense
|
|
288
279
|
fallback={
|
package/src/index.ts
CHANGED
|
@@ -50,6 +50,7 @@ export * from "./DnDList";
|
|
|
50
50
|
export * from "./DraggablePaperComponent";
|
|
51
51
|
export * from "./EmailInput";
|
|
52
52
|
export * from "./FabBox";
|
|
53
|
+
export * from "./FileUploadButton";
|
|
53
54
|
export * from "./FlexBox";
|
|
54
55
|
export * from "./GridDataFormat";
|
|
55
56
|
export * from "./HiSelector";
|
package/src/pages/ViewPage.tsx
CHANGED
|
@@ -65,7 +65,7 @@ type ViewPageFieldTypeNarrow<T extends object> =
|
|
|
65
65
|
*/
|
|
66
66
|
export type ViewPageFieldType<T extends object> =
|
|
67
67
|
| ViewPageFieldTypeNarrow<T>
|
|
68
|
-
| ((data: T) => React.ReactNode);
|
|
68
|
+
| ((data: T, refresh: () => Promise<void>) => React.ReactNode);
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* View page props
|
|
@@ -276,7 +276,7 @@ export function ViewPage<T extends DataTypes.StringRecord>(
|
|
|
276
276
|
// Get data
|
|
277
277
|
if (typeof field === "function") {
|
|
278
278
|
// Most flexible way, do whatever you want
|
|
279
|
-
return field(data);
|
|
279
|
+
return field(data, refresh);
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
const [itemData, itemLabel, gridProps] = getItemField(
|