Skip to content

Commit

Permalink
fix(file-upload): fix coderabbitai reported bugs and markdown
Browse files Browse the repository at this point in the history
  • Loading branch information
Arian94 committed Nov 6, 2024
1 parent 6926e7b commit 7ca7d22
Show file tree
Hide file tree
Showing 16 changed files with 170 additions and 70 deletions.
23 changes: 0 additions & 23 deletions apps/docs/content/components/file-upload/button.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
const App = `
import {FileUpload} from "@nextui-org/react";
import {SearchIcon, DeleteIcon} from "@nextui-org/shared-icons";
export default function App() {
return (
<FileUpload
multiple
buttons={(onBrowse, onAdd, onReset) => {
return <div>
<Button onClick={() => onBrowse()}><SearchIcon /></Button>
<Button onClick={() => onBrowse()}>Browse Files</Button>
<Button onClick={() => onAdd()}>Add New File</Button>
<Button onClick={() => onReset()}>Remove All</Button>
</div>
Expand Down
23 changes: 12 additions & 11 deletions apps/docs/content/components/file-upload/controlled.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
const App = `
import React from "react";
import {FileUpload} from "@nextui-org/react";
import {useEffect} from "react";
import {filesFromApi} from "./filesFromApi";
const filesFromApi = async () => {
return [
new File([], "file1", {type: "jpg"}),
new File([], "file2", {type: "jpg"}),
new File([], "file3", {type: "jpg"}),
];
}
const filesFromApi= new Promise((res) => {
res([
new File(['dummy content'], "file1.jpg", {type: "image/jpeg"}),
new File(['dummy content'], "file2.jpg", {type: "image/jpeg"}),
new File(['dummy content'], "file3.jpg", {type: "image/jpeg"}),
]);
});
export default function App() {
const [files, setFiles] = useState<File[]>();
const [files, setFiles] = React.useState([]);
useEffect(() => {
filesFromApi().then(files => setFiles(files));
React.useEffect(() => {
filesFromApi.then(files => setFiles(files));
}, []);
return (
Expand Down
58 changes: 58 additions & 0 deletions apps/docs/content/components/file-upload/customButtons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const DeleteIcon = `export const DeleteIcon = ({
fill = 'currentColor',
filled,
size,
height,
width,
label,
...props
}) => {
return (
<svg aria-hidden="true" fill="none" focusable="false" height="1em" role="presentation"
viewBox="0 0 20 20" width="1em">
<path
d="M17.5 4.98332C14.725 4.70832 11.9333 4.56665 9.15 4.56665C7.5 4.56665 5.85 4.64998 4.2 4.81665L2.5 4.98332"
stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5"></path>
<path
d="M7.08331 4.14169L7.26665 3.05002C7.39998 2.25835 7.49998 1.66669 8.90831 1.66669H11.0916C12.5 1.66669 12.6083 2.29169 12.7333 3.05835L12.9166 4.14169"
stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5"></path>
<path
d="M15.7084 7.61664L15.1667 16.0083C15.075 17.3166 15 18.3333 12.675 18.3333H7.32502C5.00002 18.3333 4.92502 17.3166 4.83335 16.0083L4.29169 7.61664"
stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5"></path>
<path d="M8.60834 13.75H11.3833" stroke="currentColor" strokeLinecap="round"
strokeLinejoin="round" strokeWidth="1.5"></path>
<path d="M7.91669 10.4167H12.0834" stroke="currentColor" strokeLinecap="round"
strokeLinejoin="round" strokeWidth="1.5"></path>
</svg>
);
};`;

const App = `
import React from "react";
import {FileUpload} from "@nextui-org/react";
import {Button} from "@nextui-org/react";
import {DeleteIcon} from './DeleteIcon';
export default function App() {
const [files, setFiles] = React.useState([]);
return (
<FileUpload
multiple
onChange={newFiles => setFiles(newFiles)}
browseButton={<Button>Search</Button>}
uploadButton={<Button onClick={() => console.log("Files to upload:\\n" + files.map(file => file.name).join("\\n"))}>Upload Files</Button>}
addButton={<Button>+</Button>}
resetButton={<Button><DeleteIcon /></Button>}
/>
);
}`;

const react = {
"/App.jsx": App,
"/DeleteIcon.jsx": DeleteIcon,
};

export default {
...react,
};
1 change: 0 additions & 1 deletion apps/docs/content/components/file-upload/file-item.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const App = `
import {FileUpload} from "@nextui-org/react";
import {SearchIcon, DeleteIcon} from "@nextui-org/shared-icons";
export default function App() {
return (
Expand Down
8 changes: 4 additions & 4 deletions apps/docs/content/components/file-upload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import usage from "./usage";
import multiple from "./multiple";
import topbar from "./topbar";
import fileItem from "./file-item";
import button from "./button";
import buttons from "./buttons";
import customButtons from "./customButtons";
import buttonsContainer from "./buttonsContainer";
import controlled from "./controlled";

export const fileUploadContent = {
usage,
multiple,
topbar,
fileItem,
button,
buttons,
customButtons,
buttonsContainer,
controlled,
};
28 changes: 14 additions & 14 deletions apps/docs/content/docs/components/file-upload.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: "File Upload adds/removes file(s) selected by user to upload on a s

import {fileUploadContent} from "@/content/components/file-upload";

# Field Upload
# File Upload

File Upload adds/removes file(s) selected by user to upload on a server.

Expand Down Expand Up @@ -66,17 +66,17 @@ There is a built-in component to display information regarding the selected file

### With Custom Upload, Browse, Add and Reset Buttons

In case you need to upload files prior to submitting the form, you can implement a custom button. In addition, there are placeholders for
other buttons such as the Add Button to place your custom button (component) instead.
If you need to have your custom buttons for browsing, adding or reseting, you can implement one for each.
In addition, there is an `uploadButton` prop for you in case uploading files prior to submitting the form is required.

<CodeDemo title="With Custom Upload, Browse, Add and Reset Buttons" files={fileUploadContent.button} />
<CodeDemo title="With Custom Upload, Browse, Add and Reset Buttons" files={fileUploadContent.customButtons} />

### With A Custom Container For Buttons Section

You can replace all the buttons entirely with your custom buttons container using the `buttons` prop.
It provides three handlers for adding a single file (`onAdd`), browsing (`onBrowse`) and removing all files (`onReset`).

<CodeDemo title="With Custom Buttons" files={fileUploadContent.buttons} />
<CodeDemo title="With Custom Buttons" files={fileUploadContent.buttonsContainer} />

### Controlled

Expand Down Expand Up @@ -109,16 +109,16 @@ the `files` prop can be set initially.
| children | `ReactNode` \| `ReactNode[]` | The contents of the collection. Usually the array of `FileUploadItem` | |
| multiple | `boolean` | Whether multiple files can be selected from the device. | false |
| isDisabled | `boolean` | Whether the FileUpload items and buttons are disabled. | false |
| classNames | `Record<"base"| "items"| "buttons, string>` | Allows to set custom class names for the FileUpload slots. | - |
| classNames | `Record<"base"| "items"| "buttons", string>` | Allows to set custom class names for the FileUpload slots. | - |
| files | `File[]` | Files as initial values or files to be controlled from outside of the FileUpload. | - |
| browseButton | `ReactHTMLElement<HTMLButtonElement>` | Custom button for browsing files. | - |
| browseButtonText | `Record<"base"| "items"| "buttons, string>` | Custom text for the default Browse Button. | - |
| addButton | `ReactHTMLElement<HTMLButtonElement>` | Custom button for adding a single file. | - |
| resetButton | `ReactHTMLElement<HTMLButtonElement>` | Custom button for reseting files to an empty array. | - |
| uploadButton | `ReactHTMLElement<HTMLButtonElement>` | Custom button for uploading files to a server. | - |
| topbar | `Record<"base"| "items"| "buttons, string>` | Custom topbar to show information regarding files. | - |
| buttons | `Record<"base"| "items"| "buttons, string>` | Custom buttons for browsing, adding, .etc or any other ones that are needed for the user. | - |
| fileItemElement | `Record<"base"| "items"| "buttons, string>` | Custom element for representing an item that is selected from the device. | - |
| browseButtonText | `string` | Custom text for the default Browse Button. | - |
| browseButton | `ReactElement<ButtonProps>` | Custom button for browsing files. | - |
| addButton | `ReactElement<ButtonProps>` | Custom button for adding a single file. | - |
| resetButton | `ReactElement<ButtonProps>` | Custom button for reseting files to an empty array. | - |
| uploadButton | `ReactElement<ButtonProps>` | Custom button for uploading files to a server. | - |
| topbar | `ReactElement<HTMLElement>` | Custom topbar to show information regarding files. | - |
| buttons | `ReactElement<HTMLElement>` | Custom buttons for browsing, adding, .etc or any other ones that are needed for the user. | - |
| fileItemElement | `ReactElement<HTMLElement>` | Custom element for representing an item that is selected from the device. | - |

### FileUpload Events

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FileUpload should render correctly 1`] = `
<div>
<div
class="flex flex-col relative overflow-hidden h-auto text-foreground box-border bg-content1 outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2"
>
<input
class="hidden"
title="file upload"
type="file"
/>
<input
class="hidden"
title="single file upload"
type="file"
/>
<div
class="flex gap-3 p-3 w-full items-center overflow-hidden color-inherit subpixel-antialiased"
>
<button
class="z-0 group relative inline-flex items-center justify-center box-border appearance-none select-none whitespace-nowrap font-normal subpixel-antialiased overflow-hidden tap-highlight-transparent data-[pressed=true]:scale-[0.97] outline-none data-[focus-visible=true]:z-10 data-[focus-visible=true]:outline-2 data-[focus-visible=true]:outline-focus data-[focus-visible=true]:outline-offset-2 px-4 min-w-20 h-10 text-small gap-2 rounded-medium [&>svg]:max-w-[theme(spacing.8)] transition-transform-colors-opacity motion-reduce:transition-none bg-default text-default-foreground data-[hover=true]:opacity-hover"
type="button"
>
Browse
</button>
</div>
</div>
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ describe("FileUpload", () => {
it("should render correctly", () => {
const wrapper = render(<FileUpload />);

expect(wrapper.getByRole("button")).toBeInTheDocument();
expect(wrapper.container).toMatchSnapshot();
expect(() => wrapper.unmount()).not.toThrow();
});

Expand Down
2 changes: 1 addition & 1 deletion packages/components/file-upload/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@nextui-org/file-upload",
"version": "2.0.0",
"description": "File Uplaod adds/removes file(s) selected by user to upload on a server.",
"description": "File Upload adds/removes file(s) selected by user to upload on a server.",
"keywords": [
"file-upload"
],
Expand Down
22 changes: 18 additions & 4 deletions packages/components/file-upload/src/file-upload-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ import {CloseIcon} from "@nextui-org/shared-icons";

export interface FileUploadItemProps extends HTMLNextUIProps<"div"> {
file: File;
onFileRemove: (name: string) => void;
onFileRemove: (file: File) => void;
isDisabled?: boolean;
}

const formatFileSize = (bytes: number) => {
if (bytes === 0) return "0 Bytes";
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));

return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

const FileUploadItem: React.FC<FileUploadItemProps> = ({
file,
onFileRemove,
Expand All @@ -16,12 +25,17 @@ const FileUploadItem: React.FC<FileUploadItemProps> = ({
}) => {
return (
<div {...otherProps}>
<Button isDisabled={isDisabled} onClick={() => onFileRemove(file.name)}>
<Button
aria-label={`Remove ${file.name}`}
isDisabled={isDisabled}
role="listitem"
onClick={() => onFileRemove(file)}
>
<CloseIcon />
</Button>
<span>{file.name}</span>
<span>{file.size}</span>
<span>{file.type}</span>
<span>{formatFileSize(file.size)}</span>
<span>{file.type.split("/").at(1)?.toUpperCase()}</span>
</div>
);
};
Expand Down
17 changes: 12 additions & 5 deletions packages/components/file-upload/src/file-upload-topbar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {clsx} from "@nextui-org/shared-utils";
import {HTMLNextUIProps} from "@nextui-org/system";
import {ReactElement} from "react";

type FileSize = `${number} KB` | `${number} MB`;
type FileSize = `${number} KB` | `${number} MB` | `${number}KB` | `${number}MB`;

export interface FileUploadTopbarProps extends HTMLNextUIProps<"div"> {
/**
Expand Down Expand Up @@ -56,25 +57,31 @@ const FileUploadTopbar: React.FC<FileUploadTopbarProps> = ({
maxAllowedSizeElement,
totalMaxAllowedSize,
totalMaxAllowedSizeElement,
className,
...otherProps
}) => {
return (
<div {...otherProps}>
<div
aria-label="File upload constraints"
className={clsx("flex gap-2 text-sm text-default-500", className)}
role="region"
{...otherProps}
>
{maxItems > 1 &&
(maxItemsElement ?? (
<span>
<span aria-label={`${maxItemsText}: ${maxItems}`}>
{maxItemsText}: {maxItems}
</span>
))}
{maxAllowedSize &&
(maxAllowedSizeElement ?? (
<span>
<span aria-label={`${maxAllowedSizeText}: ${maxAllowedSize}`}>
{maxAllowedSizeText}: {maxAllowedSize}
</span>
))}
{totalMaxAllowedSize &&
(totalMaxAllowedSizeElement ?? (
<span>
<span aria-label={`${totalMaxAllowedSizeText}: ${totalMaxAllowedSize}`}>
{totalMaxAllowedSizeText}: {totalMaxAllowedSize}
</span>
))}
Expand Down
Loading

0 comments on commit 7ca7d22

Please sign in to comment.