@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: import("react").ForwardRefExoticComponent<import("react").HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
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.34",
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": "cc3e285416d8c9184e0bf597400550d08847001e"
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 { DirectionOptions, FileUploaderProps } from "./types";
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 = forwardRef<
266
- HTMLDivElement,
267
- React.HTMLAttributes<HTMLDivElement>
268
- >(({ className, children, ...props }, ref) => {
269
- const { dropzoneState, isFileTooBig, isLOF } = useFileUpload();
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
- ref={dropzoneState.inputRef}
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
  };