Skip to content

Commit

Permalink
feat: create DropZoneContent and FileList components
Browse files Browse the repository at this point in the history
  • Loading branch information
typeWolffo committed Aug 5, 2024
1 parent 0b728df commit 4dc1a89
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { first, isEmpty } from "lodash-es";
import pluralize from "pluralize";

interface DropZoneContentProps {
files: File[];
multiple?: boolean;
}

export default function DropzoneContent({
files,
multiple,
}: DropZoneContentProps) {
if (!multiple && !isEmpty(files) && first(files)?.type.startsWith("image/")) {
return (
<img
src={URL.createObjectURL(files[0])}
alt="Preview"
className="w-full h-full rounded-lg object-cover"
/>
);
}
return (
<span className="text-center">
Drag and drop or click to upload {pluralize("file", multiple ? 2 : 1)}
</span>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { isEmpty } from "lodash-es";
import { Label } from "../ui/label";
import FileListItemIcon from "./FileListIcon";
import FileListItem from "./FileListItem";
import pluralize from "pluralize";

interface FileListProps {
files: File[];
onRemoveFile: (index: number) => void;
}

export default function FileList({ files, onRemoveFile }: FileListProps) {
if (isEmpty(files)) return null;

return (
<div className="space-y-2">
<Label>Selected {pluralize("file", files.length)}</Label>
<ul className="space-y-2">
{files.map((file, index) => (
<FileListItem
key={`${file.name}-${index}`}
index={index}
file={file}
onRemove={onRemoveFile}
icon={<FileListItemIcon fileName={file.name} className="h-6 w-6" />}
/>
))}
</ul>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from "react";
import {
LucideProps,
FileText,
FileAudio,
FileVideo,
FileSpreadsheet,
FileQuestion,
} from "lucide-react";
import { last } from "lodash-es";

interface FileListItemIconProps extends LucideProps {
fileName: string;
}

const FILE_TYPES = [
{ extensions: ["txt", "doc", "docx", "pdf"], Icon: FileText },
{ extensions: ["mp3", "wav", "ogg"], Icon: FileAudio },
{ extensions: ["mp4", "avi", "mov"], Icon: FileVideo },
{ extensions: ["xls", "xlsx", "csv"], Icon: FileSpreadsheet },
];

function getFileIcon(fileName: string): React.ComponentType<LucideProps> {
const extension = last(fileName.split("."))?.toLowerCase();
if (!extension) return FileQuestion;

const fileType = FILE_TYPES.find((type) =>
type.extensions.includes(extension)
);
return fileType ? fileType.Icon : FileQuestion;
}

export default function FileListItemIcon({
fileName,
...props
}: FileListItemIconProps) {
const Icon = getFileIcon(fileName);
return <Icon {...props} />;
}

0 comments on commit 4dc1a89

Please sign in to comment.