@mbao01/common 0.0.34 → 0.0.36
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,10 +1,13 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type { FileUploaderProps } from "./types";
|
|
2
|
+
import type { FileUploaderInputProps, FileUploaderProps } from "./types";
|
|
3
3
|
export declare const FileUploader: {
|
|
4
4
|
({ className, dropzoneOptions, value, onValueChange, reSelect, orientation, children, dir, ...props }: FileUploaderProps): import("react/jsx-runtime").JSX.Element;
|
|
5
5
|
displayName: string;
|
|
6
6
|
Content: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
|
|
7
|
-
Input:
|
|
7
|
+
Input: {
|
|
8
|
+
({ className, children, ...props }: FileUploaderInputProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
displayName: string;
|
|
10
|
+
};
|
|
8
11
|
Item: import("react").ForwardRefExoticComponent<{
|
|
9
12
|
index: number;
|
|
10
13
|
} & import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Dispatch, SetStateAction } from "react";
|
|
1
|
+
import type { Dispatch, Ref, SetStateAction } from "react";
|
|
2
2
|
import type { DropzoneState, DropzoneOptions } from "react-dropzone";
|
|
3
3
|
export type FileUploaderProps = {
|
|
4
4
|
value: File[] | null;
|
|
@@ -7,14 +7,17 @@ export type FileUploaderProps = {
|
|
|
7
7
|
dropzoneOptions: DropzoneOptions;
|
|
8
8
|
orientation?: "horizontal" | "vertical";
|
|
9
9
|
} & React.HTMLAttributes<HTMLDivElement>;
|
|
10
|
+
export type FileUploaderInputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
|
10
11
|
export type DirectionOptions = "rtl" | "ltr" | undefined;
|
|
11
12
|
export type FileUploaderContextType = {
|
|
12
13
|
dropzoneState: DropzoneState;
|
|
13
14
|
isLOF: boolean;
|
|
14
15
|
isFileTooBig: boolean;
|
|
15
16
|
removeFileFromSet: (index: number) => void;
|
|
17
|
+
removeAll: () => void;
|
|
16
18
|
activeIndex: number;
|
|
17
19
|
setActiveIndex: Dispatch<SetStateAction<number>>;
|
|
18
20
|
orientation: "horizontal" | "vertical";
|
|
19
21
|
direction: DirectionOptions;
|
|
22
|
+
hiddenInputRef: Ref<HTMLInputElement>;
|
|
20
23
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mbao01/common",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.36",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Ayomide Bakare",
|
|
7
7
|
"license": "MIT",
|
|
@@ -145,5 +145,5 @@
|
|
|
145
145
|
"react-dom": "^18.2.0",
|
|
146
146
|
"typescript": "^5.2.2"
|
|
147
147
|
},
|
|
148
|
-
"gitHead": "
|
|
148
|
+
"gitHead": "56575cccb960383ac1b9397068161bbd1b25a477"
|
|
149
149
|
}
|
|
@@ -4,7 +4,11 @@ import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
|
|
|
4
4
|
import { useDropzone, FileRejection } from "react-dropzone";
|
|
5
5
|
import { toast } from "sonner";
|
|
6
6
|
import { TrashIcon } from "@radix-ui/react-icons";
|
|
7
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
DirectionOptions,
|
|
9
|
+
FileUploaderInputProps,
|
|
10
|
+
FileUploaderProps,
|
|
11
|
+
} from "./types";
|
|
8
12
|
import { cn } from "../../utilities";
|
|
9
13
|
import { FileUploaderContext } from "./FileUploaderContext";
|
|
10
14
|
import { useFileUpload } from "./useFileUpload";
|
|
@@ -20,6 +24,7 @@ export const FileUploader = ({
|
|
|
20
24
|
dir,
|
|
21
25
|
...props
|
|
22
26
|
}: FileUploaderProps) => {
|
|
27
|
+
const hiddenInputRef = useRef<HTMLInputElement>(null);
|
|
23
28
|
const [isFileTooBig, setIsFileTooBig] = useState(false);
|
|
24
29
|
const [isLOF, setIsLOF] = useState(false);
|
|
25
30
|
const [activeIndex, setActiveIndex] = useState(-1);
|
|
@@ -44,6 +49,10 @@ export const FileUploader = ({
|
|
|
44
49
|
[value, onValueChange]
|
|
45
50
|
);
|
|
46
51
|
|
|
52
|
+
const removeAll = useCallback(() => {
|
|
53
|
+
onValueChange(null);
|
|
54
|
+
}, [onValueChange]);
|
|
55
|
+
|
|
47
56
|
const handleKeyDown = useCallback(
|
|
48
57
|
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
|
49
58
|
e.preventDefault();
|
|
@@ -123,6 +132,16 @@ export const FileUploader = ({
|
|
|
123
132
|
|
|
124
133
|
onValueChange(newValues);
|
|
125
134
|
|
|
135
|
+
if (hiddenInputRef.current) {
|
|
136
|
+
// Note the specific way we need to munge the file into the hidden input
|
|
137
|
+
// https://stackoverflow.com/a/68182158/1068446
|
|
138
|
+
const dataTransfer = new DataTransfer();
|
|
139
|
+
newValues.forEach((v) => {
|
|
140
|
+
dataTransfer.items.add(v);
|
|
141
|
+
});
|
|
142
|
+
hiddenInputRef.current.files = dataTransfer.files;
|
|
143
|
+
}
|
|
144
|
+
|
|
126
145
|
if (rejectedFiles.length > 0) {
|
|
127
146
|
for (const rejectedFile of rejectedFiles) {
|
|
128
147
|
if (rejectedFile.errors[0]?.code === "file-too-large") {
|
|
@@ -169,10 +188,12 @@ export const FileUploader = ({
|
|
|
169
188
|
isLOF,
|
|
170
189
|
isFileTooBig,
|
|
171
190
|
removeFileFromSet,
|
|
191
|
+
removeAll,
|
|
172
192
|
activeIndex,
|
|
173
193
|
setActiveIndex,
|
|
174
194
|
orientation,
|
|
175
195
|
direction,
|
|
196
|
+
hiddenInputRef,
|
|
176
197
|
}}
|
|
177
198
|
>
|
|
178
199
|
<div
|
|
@@ -262,15 +283,16 @@ const FileUploaderItem = forwardRef<
|
|
|
262
283
|
|
|
263
284
|
FileUploaderItem.displayName = "FileUploaderItem";
|
|
264
285
|
|
|
265
|
-
const FileUploaderInput =
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
286
|
+
const FileUploaderInput = ({
|
|
287
|
+
className,
|
|
288
|
+
children,
|
|
289
|
+
...props
|
|
290
|
+
}: FileUploaderInputProps) => {
|
|
291
|
+
const { dropzoneState, isFileTooBig, isLOF, hiddenInputRef } =
|
|
292
|
+
useFileUpload();
|
|
270
293
|
const rootProps = isLOF ? {} : dropzoneState.getRootProps();
|
|
271
294
|
return (
|
|
272
295
|
<div
|
|
273
|
-
ref={ref}
|
|
274
296
|
{...props}
|
|
275
297
|
className={`relative w-full ${
|
|
276
298
|
isLOF ? "opacity-50 cursor-not-allowed " : "cursor-pointer "
|
|
@@ -293,14 +315,20 @@ const FileUploaderInput = forwardRef<
|
|
|
293
315
|
{children}
|
|
294
316
|
</div>
|
|
295
317
|
<input
|
|
296
|
-
|
|
318
|
+
{...props}
|
|
319
|
+
ref={hiddenInputRef}
|
|
320
|
+
type="file"
|
|
321
|
+
style={{ opacity: 0, display: "none" }}
|
|
322
|
+
/>
|
|
323
|
+
<input
|
|
297
324
|
disabled={isLOF}
|
|
325
|
+
ref={dropzoneState.inputRef}
|
|
298
326
|
{...dropzoneState.getInputProps()}
|
|
299
327
|
className={`${isLOF ? "cursor-not-allowed" : ""}`}
|
|
300
328
|
/>
|
|
301
329
|
</div>
|
|
302
330
|
);
|
|
303
|
-
}
|
|
331
|
+
};
|
|
304
332
|
|
|
305
333
|
FileUploaderInput.displayName = "FileInput";
|
|
306
334
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Dispatch, SetStateAction } from "react";
|
|
1
|
+
import type { Dispatch, Ref, SetStateAction } from "react";
|
|
2
2
|
import type { DropzoneState, DropzoneOptions } from "react-dropzone";
|
|
3
3
|
|
|
4
4
|
export type FileUploaderProps = {
|
|
@@ -9,6 +9,9 @@ export type FileUploaderProps = {
|
|
|
9
9
|
orientation?: "horizontal" | "vertical";
|
|
10
10
|
} & React.HTMLAttributes<HTMLDivElement>;
|
|
11
11
|
|
|
12
|
+
export type FileUploaderInputProps =
|
|
13
|
+
React.InputHTMLAttributes<HTMLInputElement>;
|
|
14
|
+
|
|
12
15
|
export type DirectionOptions = "rtl" | "ltr" | undefined;
|
|
13
16
|
|
|
14
17
|
export type FileUploaderContextType = {
|
|
@@ -16,8 +19,10 @@ export type FileUploaderContextType = {
|
|
|
16
19
|
isLOF: boolean;
|
|
17
20
|
isFileTooBig: boolean;
|
|
18
21
|
removeFileFromSet: (index: number) => void;
|
|
22
|
+
removeAll: () => void;
|
|
19
23
|
activeIndex: number;
|
|
20
24
|
setActiveIndex: Dispatch<SetStateAction<number>>;
|
|
21
25
|
orientation: "horizontal" | "vertical";
|
|
22
26
|
direction: DirectionOptions;
|
|
27
|
+
hiddenInputRef: Ref<HTMLInputElement>;
|
|
23
28
|
};
|