diff --git a/frontend/README.md b/frontend/README.md
index 64905a8..072db70 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -2,7 +2,9 @@
-![NPM Downloads](https://img.shields.io/npm/d18m/%40cubone%2Freact-file-manager?style=for-the-badge) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/%40cubone%2Freact-file-manager?style=for-the-badge) ![NPM Version](https://img.shields.io/npm/v/%40cubone%2Freact-file-manager?style=for-the-badge&color=%23c87d32)
+![NPM Downloads](https://img.shields.io/npm/d18m/%40cubone%2Freact-file-manager?style=for-the-badge)
+![npm bundle size](https://img.shields.io/bundlephobia/minzip/%40cubone%2Freact-file-manager?style=for-the-badge)
+![NPM Version](https://img.shields.io/npm/v/%40cubone%2Freact-file-manager?style=for-the-badge&color=%23c87d32)
@@ -12,13 +14,19 @@ An open-source React.js package for easy integration of a file manager into appl
## ✨ Features
-- **File & Folder Management**: View, upload, download, delete, copy, move, create, and rename files or folders seamlessly.
+- **File & Folder Management**: View, upload, download, delete, copy, move, create, and rename files
+ or folders seamlessly.
- **Grid & List View**: Switch between grid and list views to browse files in your preferred layout.
-- **Navigation**: Use the breadcrumb trail and sidebar navigation pane for quick directory traversal.
-- **Toolbar & Context Menu**: Access all common actions (upload, download, delete, copy, move, rename, etc.) via the toolbar or right-click for the same options in the context menu.
-- **Multi-Selection**: Select multiple files and folders at once to perform bulk actions like delete, copy, move, or download.
-- **Keyboard Shortcuts**: Quickly perform file operations like copy, paste, delete, and more using intuitive keyboard shortcuts.
-- **Drag-and-Drop**: Move selected files and folders by dragging them to the desired directory, making file organization effortless.
+- **Navigation**: Use the breadcrumb trail and sidebar navigation pane for quick directory
+ traversal.
+- **Toolbar & Context Menu**: Access all common actions (upload, download, delete, copy, move,
+ rename, etc.) via the toolbar or right-click for the same options in the context menu.
+- **Multi-Selection**: Select multiple files and folders at once to perform bulk actions like
+ delete, copy, move, or download.
+- **Keyboard Shortcuts**: Quickly perform file operations like copy, paste, delete, and more using
+ intuitive keyboard shortcuts.
+- **Drag-and-Drop**: Move selected files and folders by dragging them to the desired directory,
+ making file organization effortless.
![React File Manager](https://github.com/user-attachments/assets/e68f750b-86bf-450d-b27e-fd3dedebf1bd)
@@ -74,7 +82,9 @@ export default App;
## 📂 File Structure
-The `files` prop accepts an array of objects, where each object represents a file or folder. You can customize the structure to meet your application needs. Each file or folder object follows the structure detailed below:
+The `files` prop accepts an array of objects, where each object represents a file or folder. You can
+customize the structure to meet your application needs. Each file or folder object follows the
+structure detailed below:
```typescript
type File = {
@@ -88,30 +98,31 @@ type File = {
## ⚙️ Props
-| Name | Type | Description |
-| ------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `acceptedFileTypes` | string | (Optional) A comma-separated list of allowed file extensions for uploading specific file types (e.g., `.txt, .png, .pdf`). If omitted, all file types are accepted. |
-| `enableFilePreview` | boolean | A boolean flag indicating whether to use the default file previewer in the file manager `default: true`. |
-| `filePreviewPath` | string | The base URL for file previews e.g.`https://example.com`, file path will be appended automatically to it i.e. `https://example.com/yourFilePath`. |
-| `fileUploadConfig` | { url: string; headers?: { [key: string]: string } } | Configuration object for file uploads. It includes the upload URL (`url`) and an optional `headers` object for setting custom HTTP headers in the upload request. The `headers` object can accept any standard or custom headers required by the server. Example: `{ url: "https://example.com/fileupload", headers: { Authorization: "Bearer" + TOKEN, "X-Custom-Header": "value" } }` |
-| `files` | Array<[File](#-file-structure)> | An array of file and folder objects representing the current directory structure. Each object includes `name`, `isDirectory`, and `path` properties. |
-| `height` | string \| number | The height of the component `default: 600px`. Can be a string (e.g., `'100%'`, `'10rem'`) or a number (in pixels). |
-| `initialPath` | string | The path of the directory to be loaded initially e.g. `/Documents`. This should be the path of a folder which is included in `files` array. Default value is `""` |
-| `isLoading` | boolean | A boolean state indicating whether the application is currently performing an operation, such as creating, renaming, or deleting a file/folder. Displays a loading state if set `true`. |
-| `layout` | "list" \| "grid" | Specifies the default layout style for the file manager. Can be either "list" or "grid". Default value is "grid". |
-| `maxFileSize` | number | For limiting the maximum upload file size in bytes. |
-| `onCreateFolder` | (name: string, parentFolder: [File](#-file-structure)) => void | A callback function triggered when a new folder is created. Use this function to update the files state to include the new folder under the specified parent folder using create folder API call to your server. |
-| `onDelete` | (files: Array<[File](#-file-structure)>) => void | A callback function is triggered when one or more files or folders are deleted. |
-| `onDownload` | (files: Array<[File](#-file-structure)>) => void | A callback function triggered when one or more files or folders are downloaded. |
-| `onError` | (error: { type: string, message: string }, file: [File](#-file-structure)) => void | A callback function triggered whenever there is an error in the file manager. Where error is an object containing `type` ("upload", etc.) and a descriptive error `message`. |
-| `onFileOpen` | (file: [File](#-file-structure)) => void | A callback function triggered when a file or folder is opened. |
-| `onFileUploaded` | (response: { [key: string]: any }) => void | A callback function triggered after a file is successfully uploaded. Provides JSON `response` holding uploaded file details, use it to extract the uploaded file details and add it to the `files` state e.g. `setFiles((prev) => [...prev, JSON.parse(response)]);` |
-| `onFileUploading` | (file: [File](#-file-structure), parentFolder: [File](#-file-structure)) => { [key: string]: any } | A callback function triggered during the file upload process. You can also return an object with key-value pairs that will be appended to the `FormData` along with the file being uploaded. The object can contain any number of valid properties. |
-| `onLayoutChange` | (layout: "list" \| "grid") => void | A callback function triggered when the layout of the file manager is changed. |
-| `onPaste` | (files: Array<[File](#-file-structure)>, destinationFolder: [File](#-file-structure), operationType: "copy" \| "move") => void | A callback function triggered when when one or more files or folders are pasted into a new location. Depending on `operationType`, use this to either copy or move the `sourceItem` to the `destinationFolder`, updating the files state accordingly. |
-| `onRefresh` | () => void | A callback function triggered when the file manager is refreshed. Use this to refresh the `files` state to reflect any changes or updates. |
-| `onRename` | (file: [File](#-file-structure), newName: string) => void | A callback function triggered when a file or folder is renamed. |
-| `width` | string \| number | The width of the component `default: 100%`. Can be a string (e.g., `'100%'`, `'10rem'`) or a number (in pixels). |
+| Name | Type | Description |
+| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `acceptedFileTypes` | string | (Optional) A comma-separated list of allowed file extensions for uploading specific file types (e.g., `.txt, .png, .pdf`). If omitted, all file types are accepted. |
+| `enableFilePreview` | boolean | A boolean flag indicating whether to use the default file previewer in the file manager `default: true`. |
+| `filePreviewPath` | string | The base URL for file previews e.g.`https://example.com`, file path will be appended automatically to it i.e. `https://example.com/yourFilePath`. |
+| `filePreviewComponent` | (file: [File](#-file-structure)) => React.ReactNode | (Optional) A callback function that provides a custom file preview. It receives the selected file as its argument and must return a valid React node, JSX element, or HTML. Use this prop to override the default file preview behavior. Example: [Custom Preview Usage](#-custom-file-preview). |
+| `fileUploadConfig` | { url: string; headers?: { [key: string]: string } } | Configuration object for file uploads. It includes the upload URL (`url`) and an optional `headers` object for setting custom HTTP headers in the upload request. The `headers` object can accept any standard or custom headers required by the server. Example: `{ url: "https://example.com/fileupload", headers: { Authorization: "Bearer" + TOKEN, "X-Custom-Header": "value" } }` |
+| `files` | Array<[File](#-file-structure)> | An array of file and folder objects representing the current directory structure. Each object includes `name`, `isDirectory`, and `path` properties. |
+| `height` | string \| number | The height of the component `default: 600px`. Can be a string (e.g., `'100%'`, `'10rem'`) or a number (in pixels). |
+| `initialPath` | string | The path of the directory to be loaded initially e.g. `/Documents`. This should be the path of a folder which is included in `files` array. Default value is `""` |
+| `isLoading` | boolean | A boolean state indicating whether the application is currently performing an operation, such as creating, renaming, or deleting a file/folder. Displays a loading state if set `true`. |
+| `layout` | "list" \| "grid" | Specifies the default layout style for the file manager. Can be either "list" or "grid". Default value is "grid". |
+| `maxFileSize` | number | For limiting the maximum upload file size in bytes. |
+| `onCreateFolder` | (name: string, parentFolder: [File](#-file-structure)) => void | A callback function triggered when a new folder is created. Use this function to update the files state to include the new folder under the specified parent folder using create folder API call to your server. |
+| `onDelete` | (files: Array<[File](#-file-structure)>) => void | A callback function is triggered when one or more files or folders are deleted. |
+| `onDownload` | (files: Array<[File](#-file-structure)>) => void | A callback function triggered when one or more files or folders are downloaded. |
+| `onError` | (error: { type: string, message: string }, file: [File](#-file-structure)) => void | A callback function triggered whenever there is an error in the file manager. Where error is an object containing `type` ("upload", etc.) and a descriptive error `message`. |
+| `onFileOpen` | (file: [File](#-file-structure)) => void | A callback function triggered when a file or folder is opened. |
+| `onFileUploaded` | (response: { [key: string]: any }) => void | A callback function triggered after a file is successfully uploaded. Provides JSON `response` holding uploaded file details, use it to extract the uploaded file details and add it to the `files` state e.g. `setFiles((prev) => [...prev, JSON.parse(response)]);` |
+| `onFileUploading` | (file: [File](#-file-structure), parentFolder: [File](#-file-structure)) => { [key: string]: any } | A callback function triggered during the file upload process. You can also return an object with key-value pairs that will be appended to the `FormData` along with the file being uploaded. The object can contain any number of valid properties. |
+| `onLayoutChange` | (layout: "list" \| "grid") => void | A callback function triggered when the layout of the file manager is changed. |
+| `onPaste` | (files: Array<[File](#-file-structure)>, destinationFolder: [File](#-file-structure), operationType: "copy" \| "move") => void | A callback function triggered when when one or more files or folders are pasted into a new location. Depending on `operationType`, use this to either copy or move the `sourceItem` to the `destinationFolder`, updating the files state accordingly. |
+| `onRefresh` | () => void | A callback function triggered when the file manager is refreshed. Use this to refresh the `files` state to reflect any changes or updates. |
+| `onRename` | (file: [File](#-file-structure), newName: string) => void | A callback function triggered when a file or folder is renamed. |
+| `width` | string \| number | The width of the component `default: 100%`. Can be a string (e.g., `'100%'`, `'10rem'`) or a number (in pixels). |
## ⌨️ Keyboard Shortcuts
@@ -135,6 +146,25 @@ type File = {
| Refresh File List | `F5` |
| Clear Selection | `Esc` |
+## Custom File Preview
+
+The `FileManager` component allows you to provide a custom file preview by passing the
+`filePreviewComponent` prop. This is an optional callback function that receives the selected file
+as an argument and must return a valid React node, JSX element, or HTML.
+
+### Usage Example
+
+```jsx
+const CustomImagePreviewer = ({ file }) => {
+ return ;
+};
+
+ }
+/>;
+```
+
## 🤝 Contributing
Contributions are welcome! To contribute:
diff --git a/frontend/src/FileManager/Actions/Actions.jsx b/frontend/src/FileManager/Actions/Actions.jsx
index 2009d95..ea75689 100644
--- a/frontend/src/FileManager/Actions/Actions.jsx
+++ b/frontend/src/FileManager/Actions/Actions.jsx
@@ -14,6 +14,7 @@ const Actions = ({
onRefresh,
maxFileSize,
filePreviewPath,
+ filePreviewComponent,
acceptedFileTypes,
triggerAction,
}) => {
@@ -44,7 +45,12 @@ const Actions = ({
},
previewFile: {
title: "Preview",
- component: ,
+ component: (
+
+ ),
width: "50%",
},
};
diff --git a/frontend/src/FileManager/Actions/PreviewFile/PreviewFile.action.jsx b/frontend/src/FileManager/Actions/PreviewFile/PreviewFile.action.jsx
index dcd82a1..fa8cf91 100644
--- a/frontend/src/FileManager/Actions/PreviewFile/PreviewFile.action.jsx
+++ b/frontend/src/FileManager/Actions/PreviewFile/PreviewFile.action.jsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import React, { useMemo, useState } from "react";
import { getFileExtension } from "../../../utils/getFileExtension";
import Loader from "../../../components/Loader/Loader";
import { useSelection } from "../../../contexts/SelectionContext";
@@ -14,7 +14,7 @@ const videoExtensions = ["mp4", "mov", "avi"];
const audioExtensions = ["mp3", "wav", "m4a"];
const iFrameExtensions = ["txt", "pdf"];
-const PreviewFileAction = ({ filePreviewPath }) => {
+const PreviewFileAction = ({ filePreviewPath, filePreviewComponent }) => {
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
const { selectedFiles } = useSelection();
@@ -22,6 +22,12 @@ const PreviewFileAction = ({ filePreviewPath }) => {
const extension = getFileExtension(selectedFiles[0].name)?.toLowerCase();
const filePath = `${filePreviewPath}${selectedFiles[0].path}`;
+ // Custom file preview component
+ const customPreview = useMemo(
+ () => filePreviewComponent?.(selectedFiles[0]),
+ [filePreviewComponent]
+ );
+
const handleImageLoad = () => {
setIsLoading(false); // Loading is complete
setHasError(false); // No error
@@ -36,6 +42,10 @@ const PreviewFileAction = ({ filePreviewPath }) => {
window.location.href = filePath;
};
+ if (React.isValidElement(customPreview)) {
+ return customPreview;
+ }
+
return (
{hasError ||
diff --git a/frontend/src/FileManager/FileManager.jsx b/frontend/src/FileManager/FileManager.jsx
index d5240e3..6e367d7 100644
--- a/frontend/src/FileManager/FileManager.jsx
+++ b/frontend/src/FileManager/FileManager.jsx
@@ -38,6 +38,7 @@ const FileManager = ({
height = "600px",
width = "100%",
initialPath = "",
+ filePreviewComponent,
}) => {
const triggerAction = useTriggerAction();
const { containerRef, colSizes, isDragging, handleMouseMove, handleMouseUp, handleMouseDown } =
@@ -97,6 +98,7 @@ const FileManager = ({
onRefresh={onRefresh}
maxFileSize={maxFileSize}
filePreviewPath={filePreviewPath}
+ filePreviewComponent={filePreviewComponent}
acceptedFileTypes={acceptedFileTypes}
triggerAction={triggerAction}
/>
@@ -145,6 +147,7 @@ FileManager.propTypes = {
height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
initialPath: PropTypes.string,
+ filePreviewComponent: PropTypes.func,
};
export default FileManager;