
Syncfusion React File Manager
- 452 installs
- 3 repo stars
- Updated July 28, 2026
- syncfusion/react-ui-components-skills
syncfusion-react-file-manager is a Syncfusion React agent skill that teaches developers to implement File Manager UIs with browsing, upload, CRUD, virtualization, and access control in React apps.
About
syncfusion-react-file-manager is an agent skill from syncfusion/react-ui-components-skills for implementing the Syncfusion React File Manager component at version 33.1.44. It walks through installation, local and remote data providers, drag-and-drop uploads, multi-select, toolbar and context-menu customization, thumbnail templates, and role-based access control. The skill links to 39 feature-specific reference guides, including virtualization patterns for lists with 1000+ files, and sits inside a 62-skill Syncfusion React catalog installable via npx skills add. Use it when you need a production file explorer in React admin tools, DAM panels, or document workflows instead of hand-rolling tree and grid file UIs.
- syncfusion-react-file-manager
Syncfusion React File Manager by the numbers
- 452 all-time installs (skills.sh)
- +56 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #956 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/react-ui-components-skills --skill syncfusion-react-file-managerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 452 |
|---|---|
| repo stars | ★ 3 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/react-ui-components-skills ↗ |
How do you add a React file manager with upload and CRUD?
Use syncfusion-react-file-manager for development tasks
Who is it for?
React developers adopting Syncfusion who need a full-featured file explorer with server integration, i18n, and WCAG-minded defaults.
Skip if: Projects avoiding commercial UI kits or teams that only need a minimal upload button without directory navigation.
When should I use this skill?
The user asks to integrate Syncfusion File Manager, wire remote file APIs, enable drag-drop uploads, or optimize large file lists in React.
What you get
React FileManager components, provider configs, toolbar or context-menu hooks, and access-control rules for local or remote storage.
- FileManager React component
- File provider configuration
- Toolbar and permission customization
By the numbers
- Documents Syncfusion React File Manager version 33.1.44
- Links to 39 feature-specific reference guides
- Repository bundles 62 Syncfusion React component skills
Files
Syncfusion React File Manager
A comprehensive guide to implementing the Syncfusion React File Manager component for building file system interfaces with rich features like drag-drop, multi-view support, custom operations, and full accessibility.
Quick Navigation
🚀 Just Getting Started? → Read Getting Started for installation and basic setup
🛠️ Need to Build File Operations? → Check File Operations (CRUD) for create, read, update, delete patterns
📊 Working with Local Data? → See Flat Data Structure for in-memory files and event-driven operations
✅ Need Multiple File Selection? → Learn Multiple Selection & Range Selection for Ctrl+Click, Shift+Click, drag selection
⚡ Handling Large File Lists? → Use Virtualization for smooth scrolling with 1000+ files
🎨 Want to Customize the UI? → See Customization & Styling for theming and layout options
⚙️ Looking for Advanced Features? → Explore Advanced Features for performance, custom providers, and API integration
♿ Need Accessibility or Multi-Language? → Visit Accessibility & Localization for WCAG and i18n
🔐 Need User Access Control? → Learn Access Control for role-based permissions and security
📤 Passing Custom Headers to Server? → See Pass Custom Value to Server for setRequestHeader and authentication
🎯 Need Advanced Customization? → Check Adding Custom Item to Context Menu and Adding Custom Item to Toolbar
🔧 Want to Enable/Disable Toolbar Items? → See Enable/Disable Toolbar Item for programmatic control
🖼️ Customizing Thumbnails & Icons? → Learn Customize Custom Thumbnail for icon templates
📁 Customizing Navigation Pane? → See Customize Navigation Pane for tree view customization
✨ Pre-selecting Items? → Learn Preselect Items for default selections
📦 File Manager Inside Dialog/Tabs? → See Nested Items for embedding in other components
When to Use This Skill
Use this skill when you need to:
- Create a file browser interface for your application
- Implement file upload and download functionality
- Build file management features (create, delete, rename, refresh)
- Support multiple view options (details and large icons)
- Add drag-and-drop capability to file management
- Customize context menus, toolbars, and styling
- Integrate accessibility features (keyboard navigation, ARIA)
- Support internationalization and RTL languages
- Connect to local or remote file systems
Component Overview
The File Manager is a graphical user interface component for managing file systems. It enables users to:
- File Operations: Read, create, delete, rename, upload, download, and refresh files
- Multiple Views: Switch between details view (sorted list) and large icons view (thumbnails)
- Navigation: Breadcrumb trails and navigation pane with tree view for hierarchy exploration
- Context Menu: Right-click menus with customizable options
- Drag-and-Drop: Drag files between folders with configurable drop zones
- Accessibility: Full WCAG compliance with keyboard navigation and screen reader support
- Localization: Multi-language support with RTL direction for right-to-left languages
- Customization: Extensive API for styling, theming, and behavior customization
Documentation and Navigation Guide
Core Features
Getting Started & Installation
📄 Read: references/getting-started.md
- Installation and package setup
- Basic file manager implementation
- CSS imports and theme configuration
- Initial configuration and setup
- Connection to file service (AjaxSettings)
File Operations (CRUD)
📄 Read: references/file-operations.md
- Create folders and files
- Read and browse file systems
- Update/rename operations
- Delete files and folders
- Upload and download functionality
- Multi-file selection and bulk operations
- File provider patterns and custom implementations
Views & Navigation
📄 Read: references/views-and-navigation.md
- Details view with columns
- Large icon view with thumbnails
- View switching and configuration
- Breadcrumb navigation control
- Navigation pane (tree view sidebar)
- Toolbar features and layout
Data Management
Flat Data Structure
📄 Read: references/flat-data.md
- Use local JSON data instead of server calls
- FileData interface and properties
- Permission management per item
- Event-driven file operations (create, delete, rename, search)
- State management with React hooks
- Backend synchronization patterns
- Large dataset performance optimization
Multiple Selection & Range Selection
📄 Read: references/multiple-selection.md
- Enable/disable multi-select capability
- Range selection by mouse drag
- Checkbox selection support
- Selection state management
- Selected items API and events
- Pre-selecting items on load
- Keyboard shortcuts (Ctrl+A, Shift+Click)
Preselect Items
📄 Read: references/preselect-the-items.md
- Programmatically select items on load
- Preselect based on file type, size, or date
- Context-aware preselection
- Selection methods (selectAll, clearSelection)
- Get selected items programmatically
Performance & Optimization
Virtualization & Performance
📄 Read: references/virtualization.md
- Enable virtual scrolling for large datasets
- Dynamic loading of files and folders
- Viewport-based rendering optimization
- Module injection and setup
- Performance limitations and workarounds
- Best practices for handling 1000+ items
User Interactions
Drag-and-Drop Features
📄 Read: references/drag-and-drop.md
- Enable/disable drag-drop functionality
- Drop area configuration
- Event handling (fileDragStart, fileDragStop, fileDropped)
- Cross-folder drag-drop
- Custom drag-drop behavior
Customization & Styling
📄 Read: references/customization.md
- Context menu customization
- Toolbar customization
- Details view column customization
- Navigation pane customization
- Tooltip customization
- Show/hide file extensions and hidden files
- Thumbnail configuration for large icons view
- CSS class and theme customization
Advanced Customization
Adding Custom Item to Context Menu
📄 Read: references/adding-custom-item-to-context-menu.md
- Add custom menu items to context menu
- Add icons to menu items
- Handle menu click events
- Conditional menu items based on file properties
- Dynamic menu customization
Adding Custom Item to Toolbar
📄 Read: references/adding-custom-item-to-toolbar.md
- Modify default toolbar items
- Add custom toolbar items
- Custom templates for toolbar
- Toolbar click handling
- Custom buttons, checkboxes, and dropdowns
Enable/Disable Toolbar Item
📄 Read: references/enable-disable-toolbar-item.md
- Enable/disable toolbar items programmatically
- Enable/disable based on selection
- Role-based toolbar control
- Disable during operations
- Permission-based toolbar control
Customize Custom Thumbnail
📄 Read: references/customize-custom-thumbnail.md
- Hide/show thumbnails
- Custom templates for large icon view
- File type-based icons
- Size-based color coding
- Date-based icon indicators
Customize Navigation Pane
📄 Read: references/customize-navigation-items.md
- Control navigation pane visibility and width
- Custom templates for navigation nodes
- Add file counts and metadata
- Color-coded folders
- Icon-based navigation styling
- Responsive navigation pane
Nested Items
📄 Read: references/nested-items.md
- Embed File Manager inside Dialog
- Embed File Manager inside Tab
- Embed File Manager inside Splitter
- File selector with File Manager
- Multi-panel layouts with File Manager
Security & Integration
Access Control
📄 Read: references/access-control.md
- Define access permissions for folders/files
- Permission types (Allow/Deny)
- Role-based access control
- Access rules for different user roles
- Backend permission validation
Pass Custom Value to Server
📄 Read: references/pass-custom-value-to-server.md
- Setting custom HTTP headers with setRequestHeader
- User authentication headers
- User identification headers
- Tracking file operations
- Department-based access
- Download operation customization
- Image loading customization
- Complete server integration patterns
Accessibility & Localization
Accessibility & Localization
📄 Read: references/accessibility-localization.md
- WCAG 2.1 compliance
- Keyboard navigation (arrow keys, enter, delete)
- ARIA attributes and roles
- Screen reader support
- Internationalization (i18n)
- Right-to-left (RTL) support
- Date and number formatting for different locales
Advanced Features
Advanced Features
📄 Read: references/advanced-features.md
- Custom file system provider implementation
- API integration patterns
- Performance optimization techniques
- Error handling and edge cases
- Event system and hooks
- Advanced search and filtering
- Custom sorting and comparison
- Nested components (File Manager in Dialog/Tabs)
Quick Start Example
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
import '@syncfusion/ej2-base/styles/material.css';
import '@syncfusion/ej2-icons/styles/material.css';
import '@syncfusion/ej2-inputs/styles/material.css';
import '@syncfusion/ej2-popups/styles/material.css';
import '@syncfusion/ej2-buttons/styles/material.css';
import '@syncfusion/ej2-splitbuttons/styles/material.css';
import '@syncfusion/ej2-navigations/styles/material.css';
import '@syncfusion/ej2-layouts/styles/material.css';
import '@syncfusion/ej2-grids/styles/material.css';
import '@syncfusion/ej2-react-filemanager/styles/material.css';
function App() {
const hostUrl = "url";
return (
<div>
<FileManagerComponent
id="file"
ajaxSettings={{
url: hostUrl + "api/FileManager/FileOperations",
getImageUrl: hostUrl + "api/FileManager/GetImage",
uploadUrl: hostUrl + "api/FileManager/Upload",
downloadUrl: hostUrl + "api/FileManager/Download"
}}
view="Details"
height="375px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</div>
);
}
export default App;Methods Reference
The File Manager provides programmatic methods to control operations:
Selection & View Control
| Method | Parameters | Purpose |
|---|---|---|
selectAll() | - | Select all files and folders in current path |
clearSelection() | - | Deselect all items |
getSelectedFiles() | - | Get array of selected file objects |
File Operations
| Method | Parameters | Purpose |
|---|---|---|
createFolder(name?) | name: string (optional) | Create new folder; opens dialog if name not provided |
renameFile(id?, name?) | id: string, name: string | Rename file/folder; opens dialog if params not provided |
deleteFiles(ids?) | ids: string[] | Delete files/folders; opens confirmation if not provided |
openFile(id) | id: string | Open file or navigate to folder |
downloadFiles(ids?) | ids: string[] (optional) | Download selected files; downloads selection if not provided |
uploadFiles() | - | Open file upload dialog |
Navigation & Refresh
| Method | Parameters | Purpose |
|---|---|---|
refreshFiles() | - | Refresh current folder contents |
refreshLayout() | - | Refresh component layout |
traverseBackward() | - | Navigate to parent directory |
filterFiles(filterData?) | filterData: Object | Apply custom filter to displayed files |
Toolbar & Menu Control
| Method | Parameters | Purpose |
|---|---|---|
disableToolbarItems(items) | items: string[] | Disable specific toolbar buttons |
enableToolbarItems(items) | items: string[] | Enable specific toolbar buttons |
getToolbarItemIndex(item) | item: string | Get toolbar item position |
disableMenuItems(items) | items: string[] | Disable context menu items |
enableMenuItems(items) | items: string[] | Enable context menu items |
getMenuItemIndex(item) | item: string | Get context menu item position |
Dialog Control
| Method | Parameters | Purpose |
|---|---|---|
closeDialog() | - | Close any open dialog |
Component Lifecycle
| Method | Parameters | Purpose |
|---|---|---|
destroy() | - | Clean up component resources |
Events Reference
File Manager provides comprehensive event hooks for customization:
File Selection Events
| Event | Args | Triggered When |
|---|---|---|
fileSelection | FileSelectionEventArgs | File/folder about to be selected (cancelable) |
fileSelect | FileSelectEventArgs | File/folder is selected/unselected |
File Navigation Events
| Event | Args | Triggered When |
|---|---|---|
fileOpen | FileOpenEventArgs | File/folder about to be opened |
fileLoad | FileLoadEventArgs | File/folder item is rendered |
File Operation Events
| Event | Args | Triggered When |
|---|---|---|
beforeFolderCreate | FolderCreateEventArgs | Folder creation requested (cancelable) |
folderCreate | FolderCreateEventArgs | Folder successfully created |
beforeRename | RenameEventArgs | Rename operation requested (cancelable) |
rename | RenameEventArgs | File/folder successfully renamed |
beforeDelete | DeleteEventArgs | Deletion requested (cancelable) |
delete | DeleteEventArgs | File/folder successfully deleted |
beforeMove | MoveEventArgs | Move/copy operation started |
move | MoveEventArgs | File/folder successfully moved/copied |
Drag & Drop Events
| Event | Args | Triggered When |
|---|---|---|
fileDragStart | FileDragEventArgs | Drag operation begins |
fileDragging | FileDragEventArgs | Dragging is in progress |
fileDragStop | FileDragEventArgs | Drag about to be dropped (cancelable) |
fileDropped | FileDragEventArgs | File/folder successfully dropped |
Upload Events
| Event | Args | Triggered When |
|---|---|---|
uploadListCreate | UploadListCreateArgs | Upload UI created (pre-upload validation) |
beforeDownload | BeforeDownloadEventArgs | Download requested |
Menu & Context Events
| Event | Args | Triggered When |
|---|---|---|
menuOpen | MenuOpenEventArgs | Context menu about to open |
menuClose | MenuCloseEventArgs | Context menu closed |
menuClick | MenuClickEventArgs | Context menu item clicked |
Search & Dialog Events
| Event | Args | Triggered When |
|---|---|---|
search | SearchEventArgs | User types in search box |
beforePopupOpen | BeforePopupOpenCloseEventArgs | Dialog about to open |
popupOpen | PopupOpenCloseEventArgs | Dialog opened |
beforePopupClose | BeforePopupOpenCloseEventArgs | Dialog about to close |
popupClose | PopupOpenCloseEventArgs | Dialog closed |
AJAX & Server Events
| Event | Args | Triggered When |
|---|---|---|
beforeSend | BeforeSendEventArgs | AJAX request sent (add custom headers) |
success | SuccessEventArgs | AJAX request succeeded |
failure | FailureEventArgs | AJAX request failed |
beforeImageLoad | BeforeImageLoadEventArgs | Image/thumbnail request sent |
Lifecycle Events
| Event | Args | Triggered When |
|---|---|---|
created | Object | Component initialization complete |
destroyed | Object | Component destroyed |
Toolbar Events
| Event | Args | Triggered When |
|---|---|---|
toolbarCreate | ToolbarCreateEventArgs | Toolbar being created |
toolbarClick | ToolbarClickEventArgs | Toolbar button clicked |
Common Patterns
1. Basic Setup Pattern
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
import '@syncfusion/ej2-react-filemanager/styles/material.css';
export default function BasicFileManager() {
return (
<FileManagerComponent
id="file"
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
view="Details"
height="500px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}Setup Steps: 1. Install @syncfusion/ej2-react-filemanager and all peer dependencies 2. Import CSS theme (material, bootstrap, bootstrap4, fabric, or tailwind) 3. Configure ajaxSettings endpoints 4. Choose view (Details or LargeIcons) 5. Inject required services (features to enable)
2. File Service Backend Pattern
Expected Endpoint Structure:
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}Backend Implementation (ASP.NET Core Example):
[ApiController]
[Route("api/[controller]")]
public class FileManagerController : ControllerBase
{
[HttpPost("FileOperations")]
public IActionResult FileOperations(
[FromForm] string action,
[FromForm] string path,
[FromForm] string name = null,
[FromForm] IFormFile uploadFiles = null)
{
switch (action)
{
case "read":
// Return files and folders at given path
return Ok(new { files = GetDirectoryContents(path) });
case "create":
// Create new folder
Directory.CreateDirectory(Path.Combine(path, name));
return Ok();
case "delete":
// Delete files/folders
return Ok();
case "rename":
// Rename file/folder
return Ok();
case "move":
// Move or copy files
return Ok();
default:
return BadRequest("Invalid action");
}
}
[HttpGet("GetImage")]
public IActionResult GetImage([FromQuery] string path)
{
// Return thumbnail or image file
var filePath = ResolvePath(path);
return PhysicalFile(filePath, "image/jpeg");
}
[HttpPost("Upload")]
public IActionResult Upload([FromForm] IFormFile uploadFiles, [FromForm] string path)
{
// Handle file upload
var filePath = Path.Combine(path, uploadFiles.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
uploadFiles.CopyTo(stream);
}
return Ok();
}
[HttpGet("Download")]
public IActionResult Download([FromQuery] string path)
{
// Return file for download
var file = System.IO.File.ReadAllBytes(path);
var fileName = Path.GetFileName(path);
return File(file, "application/octet-stream", fileName);
}
}3. State Management Pattern
import React, { useRef, useState } from 'react';
export default function FileManagerWithState() {
const fileManagerRef = useRef(null);
const [selectedFiles, setSelectedFiles] = useState([]);
const [currentPath, setCurrentPath] = useState('/');
const handleFileSelect = (args) => {
setSelectedFiles(args.fileDetails);
};
const handleCreateFolder = () => {
fileManagerRef.current?.createFolder('NewFolder');
};
const handleDeleteSelected = () => {
const ids = selectedFiles.map(f => f.name);
fileManagerRef.current?.deleteFiles(ids);
};
return (
<div>
<div className="toolbar">
<button onClick={handleCreateFolder}>Create Folder</button>
<button onClick={handleDeleteSelected} disabled={!selectedFiles.length}>
Delete ({selectedFiles.length})
</button>
<span>Path: {currentPath}</span>
</div>
<FileManagerComponent
ref={fileManagerRef}
fileSelect={handleFileSelect}
ajaxSettings={{...}}
height="400px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</div>
);
}4. Event-Driven Custom Logic Pattern
<FileManagerComponent
// Prevent deletion of certain files
beforeDelete={(args) => {
if (args.fileDetails[0].name.startsWith('.')) {
args.cancel = true;
alert('Cannot delete system files');
}
}}
// Add headers to AJAX requests
beforeSend={(args) => {
args.headers = { ...args.headers, 'Authorization': `Bearer ${token}` };
}}
// Validate before upload
uploadListCreate={(args) => {
args.fileDetails.forEach(file => {
if (file.size > 5000000) { // 5MB limit
args.cancel = true;
}
});
}}
// Track successful operations
success={(args) => {
console.log('Operation successful:', args.action, args.result);
}}
// Handle errors
failure={(args) => {
console.error('Operation failed:', args.error);
}}
/>5. Customization Pattern
<FileManagerComponent
// Customize toolbar
toolbarSettings={{
items: ['NewFolder', 'Upload', '|', 'Cut', 'Copy', 'Paste', '|', 'Delete', 'Download'],
visible: true
}}
// Customize context menu
contextMenuSettings={{
file: ['Open', '|', 'Cut', 'Copy', '|', 'Delete', 'Rename', '|', 'Details'],
folder: ['Open', '|', 'Cut', 'Copy', 'Paste', '|', 'Delete', 'Rename'],
layout: ['SortBy', 'View', 'Refresh', '|', 'NewFolder', 'Upload'],
visible: true
}}
// Customize columns in details view
detailsViewSettings={{
columns: [
{
field: 'name',
headerText: 'Name',
minWidth: 120,
template: '<span class="custom-name">${name}</span>'
},
{
field: '_fm_modified',
headerText: 'Modified',
type: 'dateTime',
format: 'MMMM dd, yyyy HH:mm',
minWidth: 120
},
{
field: 'size',
headerText: 'Size',
minWidth: 90,
template: '<span>${size}</span>'
}
]
}}
// Customize navigation pane
navigationPaneSettings={{
maxWidth: '650px',
minWidth: '240px',
visible: true,
sortOrder: 'None'
}}
/>6. Performance Optimization Pattern
<FileManagerComponent
// Enable virtualization for large datasets
enableVirtualization={true}
// Enable persistence to maintain state
enablePersistence={true}
// Configure search settings
searchSettings={{
allowSearchOnTyping: true,
filterType: 'contains',
ignoreCase: true
}}
// Configure upload settings
uploadSettings={{
autoUpload: true,
minFileSize: 0,
maxFileSize: 30000000, // 30MB
allowedExtensions: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx',
autoClose: false,
directoryUpload: false,
sequentialUpload: false
}}
// Sort optimization
sortBy="name"
sortOrder="Ascending"
/>Key Props
Core Configuration
| Prop | Type | Default | Purpose |
|---|---|---|---|
ajaxSettings | Object | See below | Configure backend endpoints for file operations |
path | string | "/" | Current folder path |
view | string | "LargeIcons" | View type: "Details" or "LargeIcons" |
width | string | "100%" | Component width |
height | string | "400px" | Component height |
Display & Behavior
| Prop | Type | Default | Purpose |
|---|---|---|---|
showFileExtension | boolean | true | Display file extensions |
showHiddenItems | boolean | false | Display hidden files/folders |
showThumbnail | boolean | true | Show thumbnails in large icons view |
showItemCheckBoxes | boolean | true | Display checkboxes on hover |
sortBy | string | "name" | Sort field: "name", "dateModified", "size" |
sortOrder | string | "Ascending" | Sort direction: "Ascending", "Descending", or "None" |
enableRtl | boolean | false | Right-to-left layout support |
locale | string | "en-US" | Localization language code |
Selection & Navigation
| Prop | Type | Default | Purpose |
|---|---|---|---|
allowMultiSelection | boolean | true | Allow selecting multiple files |
enableRangeSelection | boolean | false | Select multiple items by dragging mouse |
selectedItems | string[] | [] | Initially selected file names |
allowDragAndDrop | boolean | false | Enable drag-drop operations |
Performance & Features
| Prop | Type | Default | Purpose |
|---|---|---|---|
enableVirtualization | boolean | false | Virtual scrolling for large datasets |
enablePersistence | boolean | false | Persist view, path, and selection state |
enableHtmlSanitizer | boolean | true | Sanitize HTML to prevent XSS attacks |
cssClass | string | "" | Custom CSS class for styling |
rootAliasName | string | null | Display name for root folder |
popupTarget | HTMLElement | null | Dialog popup target element |
Data & Settings Objects
| Prop | Type | Purpose |
|---|---|---|
fileSystemData | Object[] | Flat data structure for local files |
contextMenuSettings | Object | Customize context menu items |
toolbarSettings | Object | Configure toolbar items and layout |
detailsViewSettings | Object | Customize columns and column widths |
navigationPaneSettings | Object | Configure sidebar behavior and appearance |
searchSettings | Object | Configure search filtering options |
uploadSettings | Object | Configure upload behavior |
sortComparer | Function | Custom sorting function |
largeIconsTemplate | string \ | Function |
navigationPaneTemplate | string \ | Function |
AJAX Settings Configuration
ajaxSettings={{
url: "url", // Main CRUD endpoint (required)
getImageUrl: "url", // Thumbnail retrieval
uploadUrl: "url", // File upload endpoint
downloadUrl: "url", // File download endpoint
// Optional: Add custom headers
// headers: { 'Authorization': 'Bearer token' }
}}Backend Endpoint Expectations:
- url - Receives POST requests with
actionparameter: read: List files in pathcreate: Create new folderdelete: Delete file/folderrename: Rename file/foldermove: Move/copy file (copy or cut)search: Search filesupload: Handle file uploadsdownload: Prepare download
- getImageUrl - GET request with
pathparameter for thumbnail image URL - uploadUrl - POST multipart form data with file upload
- downloadUrl - Initiate file download stream
Common Use Cases
Case 1: Document Management System
Implement a document browser with upload, download, and folder organization:
- Use Details view for metadata display
- Configure context menu for document operations
- Add search functionality
- Implement access control on backend
Case 2: Media File Browser
Build a gallery with image/video thumbnails:
- Use Large Icons view for thumbnail display
- Configure
getImageUrlfor preview generation - Implement lazy loading for performance
- Add drag-drop for organization
Case 3: Admin File Manager
Create an internal file management tool:
- Customize toolbar with admin-specific actions
- Implement advanced context menu options
- Add logging and audit trails
- Configure permissions on backend
Case 4: Localized File Manager
Support multiple languages and RTL:
- Set
localeto user's language - Enable
enableRtlfor RTL languages - Customize context menu labels per language
- Format dates and sizes per locale
---
Next Steps
1. Start: Read references/getting-started.md for installation and basic setup 2. Implement: Choose the feature references that match your requirements 3. Customize: Review references/customization.md for styling and configuration 4. Optimize: Check references/advanced-features.md for performance and edge cases 5. Accessibility: Ensure compliance with references/accessibility-localization.md
---
Access Control in React File Manager
The React File Manager component allows you to define granular access permissions for folders and files using access rules and role-based permissions. This is essential for multi-user systems where different users should have different access levels to files and folders.
Table of Contents
1. Understanding Access Rules 2. Permission Types 3. Implementing Role-Based Access 4. Access Rules for Different User Roles 5. Complete Implementation Example
Understanding Access Rules
Access rules define what operations users in specific roles can perform on files and folders. Each rule specifies:
- Path: The file or folder path to which the rule applies
- Role: The user role for which the rule applies
- IsFile: Whether the rule applies to files (true) or folders (false)
- Permissions: Individual permission flags (Read, Write, Copy, Download, Upload, etc.)
Access Rule Properties
| Property | Applicable to Files | Applicable to Folders | Description |
|---|---|---|---|
copy | ✓ | ✓ | Allows copying files or folders |
read | ✓ | ✓ | Allows reading/viewing files or folders |
write | ✓ | ✓ | Allows modifying files or folders |
writeContents | ✗ | ✓ | Allows modifying folder contents |
download | ✓ | ✓ | Allows downloading files or folders |
upload | ✗ | ✓ | Allows uploading files to folders |
Permission Types
Allow vs Deny
// Permission values
enum Permission {
Allow = 'Allow', // Allows the operation
Deny = 'Deny' // Denies the operation
}Implementing Role-Based Access
Step 1: Backend Configuration (Server-Side)
First, define access rules on your backend file provider:
// Backend Access Rules Example (C# / ASP.NET Core)
public class FileManagerController : Controller
{
private FileAccessController fileAccessController;
public FileManagerController()
{
// Initialize with access rules
this.fileAccessController = new FileAccessController();
this.fileAccessController.SetRules(GetAccessRules());
}
private List<AccessRule> GetAccessRules()
{
return new List<AccessRule>
{
// Administrator - Full access to all files
new AccessRule
{
Path = "/*.*",
Role = "Administrator",
Read = Permission.Allow,
Write = Permission.Allow,
Copy = Permission.Allow,
Download = Permission.Allow,
IsFile = true
},
// Administrator - Full access to all folders
new AccessRule
{
Path = "*",
Role = "Administrator",
Read = Permission.Allow,
Write = Permission.Allow,
Copy = Permission.Allow,
WriteContents = Permission.Allow,
Upload = Permission.Allow,
Download = Permission.Deny,
IsFile = false
},
// Default User - Restricted access
new AccessRule
{
Path = "/*.*",
Role = "Default User",
Read = Permission.Deny,
Write = Permission.Deny,
Copy = Permission.Deny,
Download = Permission.Deny,
IsFile = true
},
// Document Manager - Specific folder access
new AccessRule
{
Path = "/Documents",
Role = "Document Manager",
Read = Permission.Allow,
Write = Permission.Allow,
Copy = Permission.Allow,
WriteContents = Permission.Allow,
Upload = Permission.Allow,
Download = Permission.Allow,
IsFile = false
},
// Document Manager - Deny access to specific file
new AccessRule
{
Path = "/Documents/Confidential.docx",
Role = "Document Manager",
Read = Permission.Deny,
Write = Permission.Deny,
Copy = Permission.Deny,
Download = Permission.Deny,
IsFile = true
}
};
}
[Route("FileOperations")]
public object FileOperations([FromBody] FileManagerDirectoryContent args)
{
// Access control is enforced through FileAccessController
return this.fileAccessController.ToCamelCase(this.fileAccessController.GetFiles(args.Path, true));
}
[Route("Upload")]
public IActionResult Upload(string path, long size, IList<IFormFile> uploadFiles, string action)
{
// Access rules prevent unauthorized uploads
return this.fileAccessController.Upload(path, uploadFiles);
}
}Step 2: Frontend Implementation
React File Manager automatically respects backend access rules. Configure the component to communicate with your access-controlled endpoints:
import React from 'react';
import { FileManagerComponent, Inject, NavigationPane, DetailsView, Toolbar } from '@syncfusion/ej2-react-filemanager';
function AccessControlExample() {
const hostUrl = "url";
return (
<div className="control-section">
<FileManagerComponent
id="file-manager"
height="500px"
view="Details"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
>
<Inject services={[NavigationPane, DetailsView, Toolbar]} />
</FileManagerComponent>
</div>
);
}
export default AccessControlExample;Access Rules for Different User Roles
Administrator Access
Full access to all files and folders:
// Administrator - Full access to files
new AccessRule
{
Path = "/*.*",
Role = "Administrator",
Read = Permission.Allow,
Write = Permission.Allow,
Copy = Permission.Allow,
Download = Permission.Allow,
IsFile = true
},
// Administrator - Full access to folders
new AccessRule
{
Path = "*",
Role = "Administrator",
Read = Permission.Allow,
Write = Permission.Allow,
Copy = Permission.Allow,
WriteContents = Permission.Allow,
Upload = Permission.Allow,
Download = Permission.Allow,
IsFile = false
}Document Manager Access
Limited access to specific folders:
// Document Manager - Read-only access to Documents folder
new AccessRule
{
Path = "/Documents",
Role = "Document Manager",
Read = Permission.Allow,
Write = Permission.Deny,
Copy = Permission.Allow,
WriteContents = Permission.Deny,
Upload = Permission.Deny,
Download = Permission.Allow,
IsFile = false
},
// Document Manager - No access to Archives folder
new AccessRule
{
Path = "/Archives",
Role = "Document Manager",
Read = Permission.Deny,
Write = Permission.Deny,
Copy = Permission.Deny,
WriteContents = Permission.Deny,
Upload = Permission.Deny,
Download = Permission.Deny,
IsFile = false
}Guest User Access
Minimal read-only access:
// Guest - Read-only access to shared files
new AccessRule
{
Path = "/Shared/*.*",
Role = "Guest",
Read = Permission.Allow,
Write = Permission.Deny,
Copy = Permission.Deny,
Download = Permission.Allow,
IsFile = true
},
// Guest - No folder modification access
new AccessRule
{
Path = "*",
Role = "Guest",
Read = Permission.Allow,
Write = Permission.Deny,
Copy = Permission.Deny,
WriteContents = Permission.Deny,
Upload = Permission.Deny,
Download = Permission.Deny,
IsFile = false
}Complete Implementation Example
Frontend Component with Access Control
import React, { useRef, useEffect } from 'react';
import { FileManagerComponent, Inject, NavigationPane, DetailsView, Toolbar, ContextMenu } from '@syncfusion/ej2-react-filemanager';
function AccessControlledFileManager() {
const fileManagerRef = useRef(null);
const userRole = localStorage.getItem('userRole') || 'Guest';
const hostUrl = "url";
useEffect(() => {
// You could validate access on component load
console.log(`File Manager loaded for role: ${userRole}`);
}, [userRole]);
const handleFileOpen = (args) => {
console.log(`Opening file: ${args.fileDetails.name}`);
// Access control is enforced server-side, but you can add client-side checks
};
const handleBeforeSend = (args) => {
// Optionally add user role to request headers
if (args.ajaxSettings) {
args.ajaxSettings.beforeSend = function(requestArgs) {
requestArgs.httpRequest.setRequestHeader('X-User-Role', userRole);
};
}
};
const handleDeleteFile = (args) => {
// Server will validate delete permission based on access rules
console.log(`Delete attempted on: ${args.fileDetails?.name}`);
};
return (
<div className="control-section">
<div className="header">
<h2>File Manager - {userRole} Access</h2>
<p>Your actions are restricted based on access control rules</p>
</div>
<FileManagerComponent
ref={fileManagerRef}
id="access-controlled-file-manager"
height="500px"
view="Details"
allowDragAndDrop={true}
allowMultiSelection={true}
showFileExtension={true}
showHiddenItems={false}
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
toolbarSettings={{
items: ['NewFolder', 'Upload', 'Delete', 'Cut', 'Copy', 'Paste', 'Rename', 'SortBy', 'Refresh', 'Selection', 'View', 'Details']
}}
contextMenuSettings={{
file: ['Open', '|', 'Cut', 'Copy', 'Delete', 'Rename', '|', 'Download', 'Details'],
folder: ['Open', '|', 'Cut', 'Copy', 'Delete', 'Rename', '|', 'Details'],
layout: ['SortBy', 'View', 'Refresh', '|', 'NewFolder', 'Upload', '|', 'Details', '|', 'SelectAll']
}}
navigationPaneSettings={{
width: '200px',
visible: true
}}
detailsViewSettings={{
columns: [
{ field: 'name', headerText: 'File Name', width: '150px' },
{ field: 'dateModified', headerText: 'Date Modified', width: '150px' },
{ field: 'size', headerText: 'Size', width: '100px' }
]
}}
beforeSend={handleBeforeSend}
fileOpen={handleFileOpen}
beforeDelete={handleDeleteFile}
>
<Inject services={[NavigationPane, DetailsView, Toolbar, ContextMenu]} />
</FileManagerComponent>
</div>
);
}
export default AccessControlledFileManager;Testing Access Control
Test different user roles to verify access restrictions:
// Test script to verify access control
// Simulate Admin access
localStorage.setItem('userRole', 'Administrator');
// Should have full access to all operations
// Simulate Document Manager access
localStorage.setItem('userRole', 'Document Manager');
// Should have limited access to Documents folder only
// Simulate Guest access
localStorage.setItem('userRole', 'Guest');
// Should have read-only access to Shared folder onlyBest Practices for Access Control
1. Always validate on server-side - Never rely solely on client-side validation 2. Use specific paths - Define rules for specific folders/files, not just wildcards 3. Principle of least privilege - Grant only necessary permissions 4. Test access rules - Verify restrictions with different user roles 5. Log access attempts - Track file access for audit purposes 6. Use HTTPS - Encrypt communication with the server 7. Implement authentication - Ensure users are properly authenticated before access control
Common Scenarios
Read-Only Access to Public Folder
new AccessRule
{
Path = "/Public/*.*",
Role = "Everyone",
Read = Permission.Allow,
Write = Permission.Deny,
Copy = Permission.Deny,
Download = Permission.Allow,
IsFile = true
}Upload-Only Access to Submissions Folder
new AccessRule
{
Path = "/Submissions",
Role = "Student",
Read = Permission.Allow,
Write = Permission.Allow,
WriteContents = Permission.Allow,
Upload = Permission.Allow,
Copy = Permission.Deny,
Download = Permission.Deny,
IsFile = false
}Deny Access to Specific File Type
new AccessRule
{
Path = "/*.exe",
Role = "User",
Read = Permission.Deny,
Write = Permission.Deny,
Download = Permission.Deny,
IsFile = true
}Related Topics
- Pass Custom Value to Server
- Customization
- File Operations
- Getting Started
Accessibility and Localization
Ensure WCAG compliance, keyboard navigation, and support for 50+ languages with RTL layouts.
Table of Contents
1. Keyboard Navigation 2. Screen Reader Support 3. Internationalization (i18n) 4. Right-to-Left (RTL) Layout 5. Complete Example
Keyboard Navigation
Built-in Keyboard Shortcuts
File Manager supports standard keyboard shortcuts:
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function AccessibleFileManager() {
return (
<FileManagerComponent
allowMultiSelection={true}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default AccessibleFileManager;Keyboard Shortcuts:
Arrow Up/Down- Navigate filesArrow Left/Right- Expand/collapse foldersSpace- Toggle file selectionCtrl+A- Select allCtrl+C- CopyCtrl+X- CutCtrl+V- PasteDelete- Delete selectedEnter- Open file/folderF2- RenameTab- Focus navigation
Manage Focus
const handleFileSelection = (args) => {
// Focus indicator automatically shown on keyboard navigation
console.log('File selected:', args.fileDetails);
};
<FileManagerComponent
fileSelect={handleFileSelection}
ajaxSettings={{...}}
allowMultiSelection={true}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Screen Reader Support
ARIA Attributes
File Manager automatically includes ARIA attributes:
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function ScreenReaderAccessible() {
return (
<div role="application" aria-label="File Manager">
<FileManagerComponent
ajaxSettings={{...}}
cssClass="accessible-fm"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</div>
);
}
export default ScreenReaderAccessible;ARIA Support Includes:
role="application"on main containeraria-labelon component sectionsaria-selectedon file itemsaria-expandedon folder itemsaria-disabledon disabled buttons- Alt text on icons and images
Test with Screen Reader
import React, { useRef } from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
function ScreenReaderTest() {
const fileManagerRef = useRef(null);
const handleCreated = () => {
console.log('File Manager created - ready for screen readers');
// Announce to screen reader
const ariaLive = document.querySelector('[aria-live="polite"]');
if (ariaLive) {
ariaLive.textContent = 'File Manager loaded. Use arrow keys to navigate.';
}
};
return (
<>
<div aria-live="polite" aria-atomic="true" className="sr-only"></div>
<FileManagerComponent
ref={fileManagerRef}
created={handleCreated}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</>
);
}
export default ScreenReaderTest;Internationalization (i18n)
Supported Locales
File Manager supports 50+ languages:
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function LocalizedFileManager() {
return (
<FileManagerComponent
locale="es" // Spanish
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default LocalizedFileManager;Supported Languages:
- English (en)
- Spanish (es)
- French (fr)
- German (de)
- Italian (it)
- Portuguese (pt)
- Russian (ru)
- Chinese Simplified (zh-CN)
- Chinese Traditional (zh-TW)
- Japanese (ja)
- Korean (ko)
- Arabic (ar)
- Hindi (hi)
- Vietnamese (vi)
- Thai (th)
- Polish (pl)
- Dutch (nl)
- Swedish (sv)
- And 32+ more...
Dynamic Locale Switching
import React, { useState } from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
function DynamicLocale() {
const [locale, setLocale] = useState('en');
return (
<>
<select onChange={(e) => setLocale(e.target.value)} value={locale}>
<option value="en">English</option>
<option value="es">Spanish</option>
<option value="fr">French</option>
<option value="de">German</option>
<option value="ja">Japanese</option>
<option value="ar">Arabic</option>
</select>
<FileManagerComponent
locale={locale}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</>
);
}
export default DynamicLocale;Custom Localization
import { L10n } from '@syncfusion/ej2-base';
// Register custom localization
L10n.load({
'es': {
'filemanager': {
'NewFolder': 'Carpeta Nueva',
'Upload': 'Subir',
'Delete': 'Eliminar',
'Rename': 'Renombrar',
'Download': 'Descargar',
'Cut': 'Cortar',
'Copy': 'Copiar',
'Paste': 'Pegar',
'Details': 'Detalles',
'GridView': 'Vista de Cuadrícula'
}
}
});
function CustomLocalizedFileManager() {
return (
<FileManagerComponent
locale="es"
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default CustomLocalizedFileManager;Right-to-Left (RTL) Layout
Enable RTL
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function RTLFileManager() {
return (
<FileManagerComponent
enableRtl={true}
locale="ar" // Arabic
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default RTLFileManager;RTL with Custom Styling
import React from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
import './rtl-styles.css';
function RTLCustom() {
return (
<div dir="rtl">
<FileManagerComponent
enableRtl={true}
locale="ar"
cssClass="rtl-file-manager"
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</div>
);
}
export default RTLCustom;CSS for RTL:
/* rtl-styles.css */
.rtl-file-manager {
direction: rtl;
}
.rtl-file-manager .e-toolbar {
direction: rtl;
text-align: right;
}
.rtl-file-manager .e-navigationpane {
border-left: 1px solid #d3d3d3;
border-right: none;
}Complete Example
import React, { useState } from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
import { L10n } from '@syncfusion/ej2-base';
import '@syncfusion/ej2-react-filemanager/styles/material.css';
// Register custom translations
L10n.load({
'es': {
'filemanager': {
'NewFolder': 'Nueva Carpeta',
'Upload': 'Subir Archivo',
'Delete': 'Eliminar',
'Rename': 'Renombrar'
}
},
'ar': {
'filemanager': {
'NewFolder': 'مجلد جديد',
'Upload': 'تحميل',
'Delete': 'حذف',
'Rename': 'إعادة تسمية'
}
}
});
function AccessibleAndLocalizedFileManager() {
const [locale, setLocale] = useState('en');
const [enableRtl, setEnableRtl] = useState(false);
const handleLocaleChange = (newLocale) => {
setLocale(newLocale);
setEnableRtl(newLocale === 'ar');
};
return (
<div>
<select onChange={(e) => handleLocaleChange(e.target.value)} value={locale}>
<option value="en">English</option>
<option value="es">Español</option>
<option value="ar">العربية</option>
<option value="fr">Français</option>
<option value="de">Deutsch</option>
</select>
<div dir={enableRtl ? 'rtl' : 'ltr'}>
<FileManagerComponent
locale={locale}
enableRtl={enableRtl}
allowMultiSelection={true}
created={() => {
// Announce to screen reader
const ariaLive = document.querySelector('[aria-live]');
if (ariaLive) {
ariaLive.textContent = `File Manager loaded in ${locale} locale`;
}
}}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
height="700px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</div>
<div aria-live="polite" aria-atomic="true" className="sr-only"></div>
</div>
);
}
export default AccessibleAndLocalizedFileManager;WCAG Compliance
Checklist
- ✅ Keyboard accessible (arrow keys, space, enter)
- ✅ Screen reader compatible (ARIA labels)
- ✅ Focus indicators visible
- ✅ Color contrast >= 4.5:1
- ✅ Localization support (50+ languages)
- ✅ RTL layout support
- ✅ Responsive design
Testing
// Test keyboard navigation
const testKeyboardNavigation = () => {
// Arrow keys should navigate files
// Tab should move focus between sections
// Enter should open/select
console.log('Test keyboard navigation manually');
};
// Test screen reader
const testScreenReader = () => {
// Use NVDA (Windows), JAWS, or VoiceOver (Mac)
// Verify all UI elements are announced
console.log('Test with screen reader');
};
// Test color contrast
const testColorContrast = () => {
// Use WCAG color contrast analyzer
console.log('Verify 4.5:1 ratio for text');
};Common Patterns
Language Selector
const languages = [
{ code: 'en', label: 'English' },
{ code: 'es', label: 'Español' },
{ code: 'fr', label: 'Français' },
{ code: 'de', label: 'Deutsch' },
{ code: 'ar', label: 'العربية' }
];
<select onChange={(e) => setLocale(e.target.value)}>
{languages.map(lang => (
<option key={lang.code} value={lang.code}>{lang.label}</option>
))}
</select>Accessibility Announcements
const announce = (message) => {
const ariaLive = document.querySelector('[aria-live="polite"]');
if (ariaLive) {
ariaLive.textContent = message;
}
};
const handleFileOpen = (args) => {
announce(`Opened: ${args.fileDetails[0].name}`);
};Next Steps
- Views: UI configuration in views-and-navigation.md
- Advanced: Performance in advanced-features.md
- Getting Started: Installation in getting-started.md
Adding Custom Items to Context Menu in React File Manager
The context menu in the React File Manager component can be customized to add custom menu items. You can add icons, event handlers, and control when menu items appear using events and settings.
Table of Contents
1. Understanding Context Menu Settings 2. Adding Custom Menu Items 3. Adding Icons to Menu Items 4. Handling Menu Clicks 5. Advanced Customization 6. Complete Example
Understanding Context Menu Settings
The contextMenuSettings property allows you to define menu items for different context types:
contextMenuSettings={{
file: ['Open', '|', 'Delete', 'Rename', '|', 'Details', 'Custom'],
folder: ['Open', '|', 'Delete', 'Rename', '|', 'Details', 'Custom'],
layout: ['SortBy', 'View', 'Refresh', '|', 'NewFolder', 'Upload', '|', 'Details', '|', 'SelectAll', 'Custom']
}}Adding Custom Menu Items
Basic Custom Menu Item
import React, { useRef } from 'react';
import { FileManagerComponent, Inject, NavigationPane, DetailsView, Toolbar } from '@syncfusion/ej2-react-filemanager';
function CustomContextMenuExample() {
const fileManagerRef = useRef(null);
const hostUrl = "url";
const handleMenuClick = (args) => {
if (args.item.text === 'Custom') {
alert(`You have clicked custom menu item on: ${args.fileDetails?.name}`);
}
};
const handleMenuOpen = (args) => {
// Add custom styling to custom menu item
for (const item of args.items) {
if (item.id === fileManagerRef.current?.element.id + '_cm_custom') {
item.iconCss = 'e-icons e-fe-settings';
}
}
};
return (
<FileManagerComponent
ref={fileManagerRef}
id="file-manager"
height="500px"
view="Details"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
contextMenuSettings={{
file: ['Open', '|', 'Delete', 'Rename', '|', 'Details', 'Custom'],
folder: ['Open', '|', 'Delete', 'Rename', '|', 'Details', 'Custom'],
layout: ['SortBy', 'View', 'Refresh', '|', 'NewFolder', 'Upload', '|', 'Details', '|', 'SelectAll', 'Custom']
}}
menuClick={handleMenuClick}
menuOpen={handleMenuOpen}
>
<Inject services={[NavigationPane, DetailsView, Toolbar]} />
</FileManagerComponent>
);
}
export default CustomContextMenuExample;Adding Icons to Menu Items
Pattern 1: Using Built-in Icons
function handleMenuOpen(args) {
for (const item of args.items) {
switch (item.id.split('_').pop()) {
case 'custom_share':
item.iconCss = 'e-icons e-share';
break;
case 'custom_archive':
item.iconCss = 'e-icons e-folder';
break;
case 'custom_encrypt':
item.iconCss = 'e-icons e-lock';
break;
case 'custom_properties':
item.iconCss = 'e-icons e-info';
break;
}
}
}Pattern 2: Using Custom Icons
function handleMenuOpen(args) {
for (const item of args.items) {
if (item.text === 'Share') {
item.iconCss = 'custom-icon-share';
} else if (item.text === 'Archive') {
item.iconCss = 'custom-icon-archive';
} else if (item.text === 'Encrypt') {
item.iconCss = 'custom-icon-encrypt';
}
}
}
// CSS for custom icons
const style = `
.custom-icon-share::before {
content: '🔗';
font-size: 16px;
}
.custom-icon-archive::before {
content: '📦';
font-size: 16px;
}
.custom-icon-encrypt::before {
content: '🔐';
font-size: 16px;
}
`;Handling Menu Clicks
Pattern 1: File Operations
function handleMenuClick(args) {
const fileName = args.fileDetails?.name;
switch (args.item.text) {
case 'Compress':
compressFile(fileName);
console.log(`Compressing file: ${fileName}`);
break;
case 'Share':
shareFile(fileName);
console.log(`Sharing file: ${fileName}`);
break;
case 'Encrypt':
encryptFile(fileName);
console.log(`Encrypting file: ${fileName}`);
break;
case 'Properties':
showFileProperties(fileName);
console.log(`Showing properties for: ${fileName}`);
break;
default:
console.log(`Menu item clicked: ${args.item.text}`);
}
}
// Handler functions
function compressFile(fileName) {
// Implementation for compression
alert(`${fileName} has been compressed`);
}
function shareFile(fileName) {
// Implementation for sharing
alert(`${fileName} sharing dialog opened`);
}
function encryptFile(fileName) {
// Implementation for encryption
alert(`${fileName} is being encrypted`);
}
function showFileProperties(fileName) {
// Implementation to show properties
alert(`Properties of ${fileName}`);
}Pattern 2: Different Actions for Files vs Folders
function handleMenuClick(args) {
const isFile = args.fileDetails?.isFile;
const itemName = args.fileDetails?.name;
if (isFile) {
// File-specific actions
if (args.item.text === 'Convert') {
convertFile(itemName);
} else if (args.item.text === 'Preview') {
previewFile(itemName);
}
} else {
// Folder-specific actions
if (args.item.text === 'Backup') {
backupFolder(itemName);
} else if (args.item.text === 'SetQuota') {
setFolderQuota(itemName);
}
}
}Pattern 3: Context-Aware Actions
function handleMenuClick(args) {
const selectedItems = fileManagerRef.current?.getSelectedFiles();
const itemCount = selectedItems?.length || 0;
if (args.item.text === 'BulkOperation') {
if (itemCount === 0) {
alert('Please select items first');
} else if (itemCount === 1) {
performSingleItemOperation(selectedItems[0]);
} else {
performBulkOperation(selectedItems);
}
}
}Advanced Customization
Pattern 1: Conditional Menu Items
function handleMenuOpen(args) {
const fileDetails = args.fileDetails;
// Show/hide items based on file properties
args.items = args.items.filter(item => {
// Hide rename for system files
if (item.text === 'Rename' && isSystemFile(fileDetails)) {
return false;
}
// Hide download for folders
if (item.text === 'Download' && !fileDetails.isFile) {
return false;
}
// Show custom items only for image files
if (item.text === 'Convert' && !isImageFile(fileDetails)) {
return false;
}
return true;
});
}
function isSystemFile(fileDetails) {
const systemFiles = ['.gitignore', '.env', 'package.json'];
return systemFiles.includes(fileDetails?.name);
}
function isImageFile(fileDetails) {
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp'];
const ext = fileDetails?.name?.substring(fileDetails.name.lastIndexOf('.'));
return imageExtensions.includes(ext?.toLowerCase());
}Pattern 2: Dynamic Menu Items Based on Permissions
function handleMenuOpen(args) {
const userRole = localStorage.getItem('userRole');
// Filter menu items based on user role
const filteredItems = args.items.filter(item => {
const permissions = {
'Admin': ['Open', 'Delete', 'Rename', 'Details', 'Admin-Tools'],
'Editor': ['Open', 'Rename', 'Details', 'Custom-Edit'],
'Viewer': ['Open', 'Details']
};
const allowedItems = permissions[userRole] || permissions['Viewer'];
return allowedItems.includes(item.text) || item.text.includes('|');
});
args.items = filteredItems;
}Pattern 3: Nested Custom Menus
function handleMenuOpen(args) {
// Add submenu items dynamically
const customItem = args.items.find(item => item.text === 'Custom');
if (customItem) {
customItem.items = [
{ text: 'Compress', id: 'custom_compress' },
{ text: 'Encrypt', id: 'custom_encrypt' },
{ text: 'Properties', id: 'custom_properties' }
];
}
}Complete Example
Full Implementation with Multiple Custom Items
import React, { useRef } from 'react';
import { FileManagerComponent, Inject, NavigationPane, DetailsView, Toolbar } from '@syncfusion/ej2-react-filemanager';
function AdvancedContextMenuExample() {
const fileManagerRef = useRef(null);
const hostUrl = "url";
const handleMenuClick = (args) => {
const itemName = args.fileDetails?.name;
const isFile = args.fileDetails?.isFile;
switch (args.item.text) {
case 'Compress':
compressItem(itemName, isFile);
break;
case 'Share':
shareItem(itemName);
break;
case 'Encrypt':
encryptItem(itemName);
break;
case 'Properties':
showProperties(itemName);
break;
case 'Backup':
if (!isFile) backupFolder(itemName);
break;
case 'SetQuota':
if (!isFile) setFolderQuota(itemName);
break;
default:
console.log(`Menu action: ${args.item.text}`);
}
};
const handleMenuOpen = (args) => {
const fileDetails = args.fileDetails;
// Add icons to custom items
for (const item of args.items) {
const itemId = item.id;
if (itemId?.includes('_cm_compress')) {
item.iconCss = 'e-icons e-redo';
} else if (itemId?.includes('_cm_share')) {
item.iconCss = 'e-icons e-share';
} else if (itemId?.includes('_cm_encrypt')) {
item.iconCss = 'e-icons e-lock';
} else if (itemId?.includes('_cm_properties')) {
item.iconCss = 'e-icons e-info';
}
}
// Filter items based on context
args.items = args.items.filter(item => {
// Hide folder-specific items for files
if (fileDetails?.isFile && ['Backup', 'SetQuota'].includes(item.text)) {
return false;
}
// Hide file-specific items for folders
if (!fileDetails?.isFile && ['Compress', 'Encrypt'].includes(item.text)) {
return false;
}
return true;
});
};
const compressItem = (name, isFile) => {
const type = isFile ? 'file' : 'folder';
alert(`${type} "${name}" has been compressed`);
};
const shareItem = (name) => {
alert(`Sharing options for "${name}"`);
};
const encryptItem = (name) => {
alert(`Encrypting "${name}"...`);
};
const showProperties = (name) => {
alert(`Properties of "${name}"`);
};
const backupFolder = (name) => {
alert(`Backing up folder "${name}"...`);
};
const setFolderQuota = (name) => {
alert(`Setting quota for folder "${name}"`);
};
return (
<div className="control-section">
<FileManagerComponent
ref={fileManagerRef}
id="advanced-context-menu"
height="500px"
view="Details"
allowDragAndDrop={true}
allowMultiSelection={true}
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
contextMenuSettings={{
file: [
'Open', '|', 'Cut', 'Copy', 'Delete', 'Rename',
'|', 'Download', 'Details', '|',
'Compress', 'Encrypt', 'Share', 'Properties'
],
folder: [
'Open', '|', 'Cut', 'Copy', 'Delete', 'Rename',
'|', 'Details', '|',
'Compress', 'Share', 'Backup', 'SetQuota', 'Properties'
],
layout: [
'SortBy', 'View', 'Refresh', '|',
'NewFolder', 'Upload', '|', 'Details', '|',
'SelectAll'
]
}}
menuClick={handleMenuClick}
menuOpen={handleMenuOpen}
>
<Inject services={[NavigationPane, DetailsView, Toolbar]} />
</FileManagerComponent>
<style>{`
.e-contextmenu .e-menu-item.e-icons::before {
font-size: 16px;
margin-right: 8px;
}
`}</style>
</div>
);
}
export default AdvancedContextMenuExample;Menu Item Separators
Use the pipe character | to add separators between menu items:
contextMenuSettings={{
file: [
'Open', '|', // Separator
'Cut', 'Copy', 'Delete',
'|', // Separator
'Rename', 'Download',
'|', // Separator
'Details', 'Compress', 'Share'
]
}}Built-in Menu Items
| Item | Context | Description |
|---|---|---|
Open | File, Folder | Opens file or folder |
Cut | File, Folder | Cuts the item |
Copy | File, Folder | Copies the item |
Delete | File, Folder | Deletes the item |
Rename | File, Folder | Renames the item |
Download | File, Folder | Downloads the item |
Details | File, Folder, Layout | Shows item details |
NewFolder | Layout | Creates new folder |
Upload | Layout | Opens upload dialog |
SortBy | Layout | Opens sort options |
View | Layout | Changes view mode |
Refresh | Layout | Refreshes file list |
SelectAll | Layout | Selects all items |
Related Topics
- Customization
- Adding Custom Item to Toolbar
- File Operations
- Getting Started
Adding Custom Items to Toolbar in React File Manager
The toolbar in the React File Manager component can be extensively customized using ToolbarItemsDirective and ToolbarItemDirective components. You can modify default items, add custom items with templates, and control toolbar appearance and behavior.
Table of Contents
1. Toolbar Configuration 2. Modifying Default Items 3. Adding Custom Items 4. Custom Templates 5. Toolbar Click Handling 6. Complete Examples
Toolbar Configuration
Using toolbarSettings Property
import React from 'react';
import { FileManagerComponent, Inject, NavigationPane, DetailsView, Toolbar } from '@syncfusion/ej2-react-filemanager';
function BasicToolbarExample() {
const hostUrl = "url";
return (
<FileManagerComponent
height="500px"
view="Details"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
toolbarSettings={{
items: [
'NewFolder', 'Upload', 'Delete', 'Cut', 'Copy', 'Paste',
'Rename', 'SortBy', 'Refresh', 'Selection', 'View', 'Details'
]
}}
>
<Inject services={[NavigationPane, DetailsView, Toolbar]} />
</FileManagerComponent>
);
}
export default BasicToolbarExample;Using ToolbarItemsDirective (Advanced)
import React from 'react';
import {
FileManagerComponent,
Inject,
NavigationPane,
DetailsView,
Toolbar,
ToolbarItemsDirective,
ToolbarItemDirective
} from '@syncfusion/ej2-react-filemanager';
function AdvancedToolbarExample() {
const hostUrl = "url";
return (
<FileManagerComponent
height="500px"
view="Details"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
>
<ToolbarItemsDirective>
<ToolbarItemDirective name="NewFolder" />
<ToolbarItemDirective name="Upload" />
<ToolbarItemDirective name="Delete" />
<ToolbarItemDirective name="Cut" />
<ToolbarItemDirective name="Copy" />
<ToolbarItemDirective name="Paste" />
<ToolbarItemDirective name="Rename" />
<ToolbarItemDirective name="SortBy" />
<ToolbarItemDirective name="View" />
<ToolbarItemDirective name="Details" />
</ToolbarItemsDirective>
<Inject services={[NavigationPane, DetailsView, Toolbar]} />
</FileManagerComponent>
);
}
export default AdvancedToolbarExample;Modifying Default Items
Pattern 1: Customize Item Text and Icon
<ToolbarItemsDirective>
<ToolbarItemDirective
name="NewFolder"
text="Create Folder"
prefixIcon="e-plus"
tooltipText="Create a new folder"
/>
<ToolbarItemDirective
name="Upload"
text="Add Files"
prefixIcon="e-upload"
tooltipText="Upload files to this folder"
/>
<ToolbarItemDirective
name="Delete"
text="Remove"
prefixIcon="e-delete"
tooltipText="Delete selected items"
/>
</ToolbarItemsDirective>Pattern 2: Reorder Toolbar Items
<ToolbarItemsDirective>
<ToolbarItemDirective name="Refresh" />
<ToolbarItemDirective name="NewFolder" />
<ToolbarItemDirective name="Upload" />
<ToolbarItemDirective name="Cut" />
<ToolbarItemDirective name="Copy" />
<ToolbarItemDirective name="Paste" />
<ToolbarItemDirective name="Delete" />
<ToolbarItemDirective name="Rename" />
<ToolbarItemDirective name="SortBy" />
<ToolbarItemDirective name="View" />
<ToolbarItemDirective name="Details" />
</ToolbarItemsDirective>Pattern 3: Hide/Show Items
<ToolbarItemsDirective>
<ToolbarItemDirective name="NewFolder" />
<ToolbarItemDirective name="Upload" />
<ToolbarItemDirective name="Delete" visible={userRole !== 'Viewer'} />
<ToolbarItemDirective name="Rename" visible={userRole !== 'Viewer'} />
<ToolbarItemDirective name="SortBy" />
<ToolbarItemDirective name="Refresh" />
<ToolbarItemDirective name="View" />
<ToolbarItemDirective name="Details" />
</ToolbarItemsDirective>Adding Custom Items
Pattern 1: Custom Button Item
<ToolbarItemsDirective>
<ToolbarItemDirective name="NewFolder" />
<ToolbarItemDirective name="Upload" />
<ToolbarItemDirective name="Separator" />
<ToolbarItemDirective
name="CustomAction"
text="Custom Action"
prefixIcon="e-execute"
tooltipText="Perform custom action"
/>
<ToolbarItemDirective name="Delete" />
<ToolbarItemDirective name="Details" />
</ToolbarItemsDirective>Pattern 2: Custom Template Item (Checkbox)
import React, { useRef } from 'react';
import { FileManagerComponent, Inject, ToolbarItemsDirective, ToolbarItemDirective } from '@syncfusion/ej2-react-filemanager';
import { CheckBoxComponent } from '@syncfusion/ej2-react-buttons';
function CheckboxToolbarExample() {
const fileManagerRef = useRef(null);
const checkboxRef = useRef(null);
const hostUrl = "url";
const handleCheckboxChange = (args) => {
if (args.checked) {
fileManagerRef.current?.selectAll();
checkboxRef.current.label = 'Unselect All';
} else {
fileManagerRef.current?.clearSelection();
checkboxRef.current.label = 'Select All';
}
};
const checkboxTemplate = () => (
<CheckBoxComponent
ref={checkboxRef}
label="Select All"
checked={false}
change={handleCheckboxChange}
/>
);
return (
<FileManagerComponent
ref={fileManagerRef}
height="500px"
view="Details"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
>
<ToolbarItemsDirective>
<ToolbarItemDirective name="NewFolder" />
<ToolbarItemDirective name="Upload" />
<ToolbarItemDirective name="Separator" />
<ToolbarItemDirective
name="SelectAll"
template={checkboxTemplate}
/>
<ToolbarItemDirective name="Separator" />
<ToolbarItemDirective name="Delete" />
<ToolbarItemDirective name="Details" />
</ToolbarItemsDirective>
<Inject services={[/* services */]} />
</FileManagerComponent>
);
}
export default CheckboxToolbarExample;Pattern 3: Custom Dropdown Item
import React, { useRef } from 'react';
import { FileManagerComponent, Inject, ToolbarItemsDirective, ToolbarItemDirective } from '@syncfusion/ej2-react-filemanager';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
function DropdownToolbarExample() {
const fileManagerRef = useRef(null);
const hostUrl = "url";
const fileTypesData = [
{ text: 'All Files', value: '*' },
{ text: 'Images', value: '*.jpg,*.png,*.gif' },
{ text: 'Documents', value: '*.pdf,*.docx,*.xlsx' },
{ text: 'Videos', value: '*.mp4,*.avi,*.mov' }
];
const handleFilterChange = (args) => {
// Apply filter based on selected file type
console.log(`Filtering by: ${args.itemData?.text}`);
};
const dropdownTemplate = () => (
<DropDownListComponent
dataSource={fileTypesData}
fields={{ text: 'text', value: 'value' }}
change={handleFilterChange}
placeholder="Filter by type"
popupHeight="200px"
/>
);
return (
<FileManagerComponent
ref={fileManagerRef}
height="500px"
view="Details"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
>
<ToolbarItemsDirective>
<ToolbarItemDirective name="NewFolder" />
<ToolbarItemDirective name="Upload" />
<ToolbarItemDirective name="Separator" />
<ToolbarItemDirective
name="FilterType"
text="Filter:"
template={dropdownTemplate}
/>
<ToolbarItemDirective name="Separator" />
<ToolbarItemDirective name="Refresh" />
<ToolbarItemDirective name="Details" />
</ToolbarItemsDirective>
<Inject services={[/* services */]} />
</FileManagerComponent>
);
}
export default DropdownToolbarExample;Toolbar Click Handling
Pattern 1: Handle Toolbar Clicks
function handleToolbarClick(args) {
if (args.item.name === 'CustomAction') {
performCustomAction();
} else if (args.item.name === 'Share') {
shareSelectedFiles();
} else if (args.item.name === 'Archive') {
archiveSelectedFiles();
}
}
function performCustomAction() {
console.log('Custom action performed');
alert('Custom action executed');
}
function shareSelectedFiles() {
const selectedItems = fileManagerRef.current?.getSelectedFiles();
alert(`Sharing ${selectedItems?.length} items`);
}
function archiveSelectedFiles() {
const selectedItems = fileManagerRef.current?.getSelectedFiles();
alert(`Archiving ${selectedItems?.length} items`);
}Pattern 2: Enable/Disable Toolbar Items
import React, { useRef } from 'react';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { FileManagerComponent, Inject } from '@syncfusion/ej2-react-filemanager';
function EnableDisableToolbarExample() {
const fileManagerRef = useRef(null);
const hostUrl = "url";
const handleEnableDelete = () => {
fileManagerRef.current?.enableToolbarItems(['delete']);
alert('Delete toolbar item enabled');
};
const handleDisableDelete = () => {
fileManagerRef.current?.disableToolbarItems(['delete']);
alert('Delete toolbar item disabled');
};
return (
<div>
<div className="button-group">
<ButtonComponent onClick={handleEnableDelete}>
Enable Delete
</ButtonComponent>
<ButtonComponent onClick={handleDisableDelete}>
Disable Delete
</ButtonComponent>
</div>
<FileManagerComponent
ref={fileManagerRef}
height="500px"
view="Details"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
toolbarSettings={{
items: ['NewFolder', 'Upload', 'Delete', 'Refresh', 'Details']
}}
>
<Inject services={[/* services */]} />
</FileManagerComponent>
</div>
);
}
export default EnableDisableToolbarExample;Complete Examples
Full Implementation with Custom Toolbar
import React, { useRef } from 'react';
import {
FileManagerComponent,
Inject,
NavigationPane,
DetailsView,
Toolbar,
ToolbarItemsDirective,
ToolbarItemDirective
} from '@syncfusion/ej2-react-filemanager';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
import { CheckBoxComponent } from '@syncfusion/ej2-react-buttons';
import { TooltipComponent } from '@syncfusion/ej2-react-popups';
function AdvancedToolbarCustomization() {
const fileManagerRef = useRef(null);
const checkboxRef = useRef(null);
const hostUrl = "url";
const handleCheckboxChange = (args) => {
if (args.checked) {
fileManagerRef.current?.selectAll();
checkboxRef.current.label = 'Unselect All';
} else {
fileManagerRef.current?.clearSelection();
checkboxRef.current.label = 'Select All';
}
};
const handleToolbarClick = (args) => {
const selectedItems = fileManagerRef.current?.getSelectedFiles();
switch (args.item.name) {
case 'Compress':
handleCompress(selectedItems);
break;
case 'Share':
handleShare(selectedItems);
break;
case 'Encrypt':
handleEncrypt(selectedItems);
break;
case 'Properties':
handleProperties(selectedItems);
break;
default:
console.log(`Toolbar action: ${args.item.name}`);
}
};
const handleCompress = (items) => {
alert(`Compressing ${items?.length} items...`);
};
const handleShare = (items) => {
alert(`Sharing ${items?.length} items...`);
};
const handleEncrypt = (items) => {
alert(`Encrypting ${items?.length} items...`);
};
const handleProperties = (items) => {
if (items?.length === 1) {
alert(`Properties of ${items[0]}`);
} else {
alert('Please select a single item');
}
};
const checkboxTemplate = () => (
<CheckBoxComponent
ref={checkboxRef}
label="Select All"
checked={false}
change={handleCheckboxChange}
/>
);
const refreshButtonTemplate = () => (
<TooltipComponent content="Refresh the file list">
<ButtonComponent
onClick={() => fileManagerRef.current?.refreshFiles()}
cssClass="e-small"
iconCss="e-icons e-refresh"
/>
</TooltipComponent>
);
return (
<div className="control-section">
<FileManagerComponent
ref={fileManagerRef}
id="advanced-toolbar"
height="500px"
view="Details"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
toolbarClick={handleToolbarClick}
>
<ToolbarItemsDirective>
<ToolbarItemDirective
name="NewFolder"
text="New Folder"
prefixIcon="e-folder-new"
tooltipText="Create new folder"
/>
<ToolbarItemDirective
name="Upload"
text="Upload"
prefixIcon="e-upload"
tooltipText="Upload files"
/>
<ToolbarItemDirective name="Separator" />
<ToolbarItemDirective
name="SelectAll"
template={checkboxTemplate}
/>
<ToolbarItemDirective name="Separator" />
<ToolbarItemDirective
name="Delete"
text="Delete"
prefixIcon="e-delete"
tooltipText="Delete selected items"
/>
<ToolbarItemDirective
name="Compress"
text="Compress"
prefixIcon="e-redo"
tooltipText="Compress selected items"
/>
<ToolbarItemDirective
name="Share"
text="Share"
prefixIcon="e-share"
tooltipText="Share selected items"
/>
<ToolbarItemDirective
name="Encrypt"
text="Encrypt"
prefixIcon="e-lock"
tooltipText="Encrypt selected items"
/>
<ToolbarItemDirective name="Separator" />
<ToolbarItemDirective
name="Refresh"
template={refreshButtonTemplate}
/>
<ToolbarItemDirective
name="View"
prefixIcon="e-view"
/>
<ToolbarItemDirective
name="Details"
text="Details"
prefixIcon="e-info"
tooltipText="Show details"
/>
</ToolbarItemsDirective>
<Inject services={[NavigationPane, DetailsView, Toolbar]} />
</FileManagerComponent>
</div>
);
}
export default AdvancedToolbarCustomization;Toolbar Item Properties
| Property | Type | Description |
|---|---|---|
name | string | Unique identifier for toolbar item |
text | string | Display text for the item |
prefixIcon | string | Icon class for item |
suffixIcon | string | Suffix icon for item |
tooltipText | string | Tooltip text on hover |
template | function/JSX | Custom template for item |
visible | boolean | Show/hide the item |
id | string | HTML id attribute |
cssClass | string | Custom CSS class |
Built-in Toolbar Items
| Item Name | Icon | Description |
|---|---|---|
NewFolder | e-folder-new | Create new folder |
Upload | e-upload | Upload files |
Cut | e-cut | Cut selected items |
Copy | e-copy | Copy selected items |
Paste | e-paste | Paste items |
Delete | e-delete | Delete selected items |
Rename | e-rename | Rename selected item |
Refresh | e-refresh | Refresh file list |
SortBy | e-sort | Sort options |
View | e-view | Change view mode |
Details | e-details | Show details |
Download | e-download | Download selected items |
Selection | e-selection | Selection options |
Separator | - | Visual separator |
Related Topics
- Adding Custom Item to Context Menu
- Enable Disable Toolbar Item
- Customization
- File Operations
Advanced Features
Master performance optimization, custom file providers, API integration patterns, and advanced implementations.
Note: For detailed guides on specific features, see:
- Virtualization: virtualization.md - Virtual scrolling for 1000+ items
- Flat Data: flat-data.md - Local JSON data structures with events
- Multiple Selection: multiple-selection.md - Multi-select, range selection, and checkboxes
Table of Contents
1. Custom File Provider 2. API Integration 3. Performance Optimization 4. Error Handling 5. Complete Example 6. Best Practices
Custom File Provider
Override Default Behavior
Use beforeSend to customize AJAX requests:
import React from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
function CustomProviderFileManager() {
const handleBeforeSend = (args) => {
// Intercept request
console.log('Request:', args.action, args.data);
// Add authorization header
args.ajaxSettings.headers = {
...args.ajaxSettings.headers,
'Authorization': 'Bearer ' + getAccessToken(),
'X-Custom-Header': 'CustomValue'
};
// Validate or modify request
if (args.action === 'delete') {
args.data.confirmDelete = true;
}
};
return (
<FileManagerComponent
beforeSend={handleBeforeSend}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default CustomProviderFileManager;
function getAccessToken() {
// Get token from localStorage or auth service
return localStorage.getItem('access_token');
}API Integration
Real-time Backend Integration
import React, { useState, useRef } from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function RealTimeAPIIntegration() {
const fileManagerRef = useRef(null);
const [status, setStatus] = useState('Ready');
const handleBeforeSend = (args) => {
// Add user context
args.ajaxSettings.data = {
...args.ajaxSettings.data,
userId: getCurrentUserId(),
tenantId: getCurrentTenantId()
};
// Log operations
console.log(`${args.action}: ${JSON.stringify(args.data)}`);
setStatus(`${args.action}...`);
};
const handleCreated = () => {
console.log('File Manager initialized');
setStatus('Ready');
};
const handleError = (args) => {
console.error('Error:', args);
setStatus(`Error: ${args.error?.message || 'Unknown'}`);
};
return (
<>
<div>Status: {status}</div>
<FileManagerComponent
ref={fileManagerRef}
beforeSend={handleBeforeSend}
created={handleCreated}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
height="600px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</>
);
}
export default RealTimeAPIIntegration;
function getCurrentUserId() {
return JSON.parse(localStorage.getItem('user'))?.id;
}
function getCurrentTenantId() {
return JSON.parse(localStorage.getItem('tenant'))?.id;
}Multi-Tenant Support
const handleBeforeSend = (args) => {
const tenantId = localStorage.getItem('tenantId');
// Include tenant in all requests
args.ajaxSettings.url = 'url';
args.ajaxSettings.headers = {
'X-Tenant-ID': tenantId,
'Authorization': 'Bearer ' + getAccessToken()
};
};Performance Optimization
Lazy Loading
import React, { useState } from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
function LazyLoadedFileManager() {
const [path, setPath] = useState('/');
const [isLoading, setIsLoading] = useState(false);
const handleBeforeSend = (args) => {
if (args.action === 'read') {
setIsLoading(true);
}
};
const handleFileOpen = (args) => {
// Load file metadata on demand
console.log('Opening:', args.fileDetails[0]);
setPath(args.fileDetails[0].filterPath);
};
const handleCreated = () => {
setIsLoading(false);
};
return (
<FileManagerComponent
beforeSend={handleBeforeSend}
fileOpen={handleFileOpen}
created={handleCreated}
enableVirtualization={true}
ajaxSettings={{...}}
height="600px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default LazyLoadedFileManager;Caching Strategy
const fileCache = new Map();
const handleBeforeSend = (args) => {
if (args.action === 'read') {
const cacheKey = args.data.path;
if (fileCache.has(cacheKey)) {
console.log('Loading from cache:', cacheKey);
args.cancel = true;
// Use cached data
} else {
// Cache will be populated on response
}
}
};Batch Operations
import React, { useRef } from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
function BatchOperationFileManager() {
const fileManagerRef = useRef(null);
const [batchInProgress, setBatchInProgress] = useState(false);
const performBatchDelete = async (fileIds) => {
setBatchInProgress(true);
try {
const response = await fetch('url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fileIds })
});
if (response.ok) {
fileManagerRef.current?.refreshFiles();
}
} finally {
setBatchInProgress(false);
}
};
return (
<FileManagerComponent
ref={fileManagerRef}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default BatchOperationFileManager;Error Handling
Graceful Error Handling
import React, { useState } from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
function ErrorHandlingFileManager() {
const [error, setError] = useState(null);
const handleBeforeSend = (args) => {
// Add timeout
args.ajaxSettings.timeout = 30000; // 30 seconds
};
const handleCreated = () => {
setError(null);
};
const handleDestroyed = () => {
console.log('File Manager destroyed');
};
return (
<>
{error && (
<div className="error-message" role="alert">
<button onClick={() => setError(null)}>×</button>
{error}
</div>
)}
<FileManagerComponent
beforeSend={handleBeforeSend}
created={handleCreated}
destroyed={handleDestroyed}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
height="600px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</>
);
}
export default ErrorHandlingFileManager;Retry Logic
const handleBeforeSend = (args) => {
let retryCount = 0;
const maxRetries = 3;
const originalUrl = args.ajaxSettings.url;
args.ajaxSettings.error = (xhr) => {
if (retryCount < maxRetries && xhr.status >= 500) {
retryCount++;
console.log(`Retry attempt ${retryCount}/${maxRetries}`);
// Retry logic handled by Syncfusion
} else {
console.error('Failed after retries:', xhr.statusText);
}
};
};Complete Example
import React, { useRef, useState } from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
import '@syncfusion/ej2-react-filemanager/styles/material.css';
function AdvancedFileManagerExample() {
const fileManagerRef = useRef(null);
const [status, setStatus] = useState('Ready');
const [error, setError] = useState(null);
const handleBeforeSend = (args) => {
// Add auth headers
args.ajaxSettings.headers = {
'Authorization': 'Bearer ' + getAccessToken(),
'X-Tenant-ID': getTenantId()
};
// Add timeout
args.ajaxSettings.timeout = 30000;
// Track operation
console.log(`Operation: ${args.action}`);
setStatus(args.action);
// Log detailed request
if (args.action === 'read') {
console.log('Reading files from:', args.data.path);
}
};
const handleCreated = () => {
setStatus('Ready');
setError(null);
};
const handleFileOpen = (args) => {
console.log('File opened:', args.fileDetails[0].name);
setStatus(`Viewing: ${args.fileDetails[0].name}`);
};
const handleDelete = (args) => {
console.log('Files deleted:', args.fileDetails.length);
};
return (
<>
{error && (
<div style={{
padding: '10px',
marginBottom: '10px',
background: '#fee',
border: '1px solid #f00',
borderRadius: '4px'
}}>
<strong>Error:</strong> {error}
<button onClick={() => setError(null)} style={{ marginLeft: '10px' }}>
Dismiss
</button>
</div>
)}
<div style={{ marginBottom: '10px', fontSize: '14px', color: '#666' }}>
Status: {status}
</div>
<FileManagerComponent
ref={fileManagerRef}
enableVirtualization={true}
view="Details"
beforeSend={handleBeforeSend}
created={handleCreated}
fileOpen={handleFileOpen}
delete={handleDelete}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
height="700px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
</>
);
}
export default AdvancedFileManagerExample;
function getAccessToken() {
return localStorage.getItem('access_token') || '';
}
function getTenantId() {
return localStorage.getItem('tenant_id') || '';
}Common Patterns
Pagination Support
const handleBeforeSend = (args) => {
if (args.action === 'read') {
// Add pagination to request
args.data = {
...args.data,
pageSize: 50,
pageNumber: 1
};
}
};Real-time Sync
const syncWithServer = setInterval(async () => {
try {
await fileManagerRef.current?.refreshFiles();
} catch (err) {
console.error('Sync failed:', err);
}
}, 5000); // Every 5 secondsSearch Integration
const handleSearch = (args) => {
console.log('Searching for:', args.searchString);
// Delegate to server-side search
};
<FileManagerComponent
search={handleSearch}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Best Practices Checklist
- Return predictable server payloads for
readand batch endpoints (includecwd,files, and per-itempermission). - Validate everything server-side (paths, sizes, extensions) even when client limits exist.
- Use per-item permissions to enable/disable UI actions and enforce checks server-side.
- Prefer transactional batch endpoints for large delete/move operations and return per-item results.
- Enable virtualization for lists with 1000+ items to reduce memory and improve UX.
- Use `beforeSend` to attach auth/tenant headers and to add telemetry/logging context.
- Sanitize custom templates and keep
enableHtmlSanitizerenabled unless you sanitize server-side. - Monitor and log operation latencies, error rates, and upload sizes.
Compact Custom Provider Example
A minimal beforeSend pattern to route requests to tenant-aware endpoints and attach auth:
const handleBeforeSend = (args) => {
const tenantId = localStorage.getItem('tenantId');
const token = localStorage.getItem('access_token');
// Route to tenant-scoped API
args.ajaxSettings.url = 'url';
// Attach headers
args.ajaxSettings.headers = {
...(args.ajaxSettings.headers || {}),
'Authorization': `Bearer ${token}`,
'X-Tenant-ID': tenantId
};
// Add contextual metadata for server-side auditing
args.ajaxSettings.data = {
...(args.ajaxSettings.data || {}),
clientTimestamp: new Date().toISOString(),
clientVersion: '1.0.0'
};
};
<FileManagerComponent
beforeSend={handleBeforeSend}
ajaxSettings={{
url: 'url',
getImageUrl: 'url',
uploadUrl: 'url',
downloadUrl: 'url'
}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Next Steps
- Customization: Styling in customization.md
- File Operations: CRUD operations in file-operations.md
- Drag-Drop: Drag-drop features in drag-and-drop.md
Customization
Customize appearance, themes, toolbars, context menus, and component structure.
Table of Contents
1. CSS Theming 2. Toolbar Customization 3. Context Menu Customization 4. View Customization 5. Complete Example
CSS Theming
Built-in Themes
Syncfusion File Manager includes Material, Bootstrap, Bootstrap4, Fabric, and Tailwind themes:
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
// Import theme CSS
import '@syncfusion/ej2-react-filemanager/styles/material.css';
// Or other themes:
// import '@syncfusion/ej2-react-filemanager/styles/bootstrap.css';
// import '@syncfusion/ej2-react-filemanager/styles/bootstrap4.css';
// import '@syncfusion/ej2-react-filemanager/styles/fabric.css';
// import '@syncfusion/ej2-react-filemanager/styles/tailwind.css';
function ThemedFileManager() {
return (
<FileManagerComponent
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default ThemedFileManager;Available Themes:
- Material (Default, Modern design)
- Bootstrap (Bootstrap styling)
- Bootstrap4 (Bootstrap 4 styling)
- Fabric (Fluent Design)
- Tailwind (Tailwind CSS compatible)
CSS Variables
Override default colors with CSS custom properties:
/* styles/custom-theme.css */
:root {
--ej2-fm-toolbar-bg: #3f51b5;
--ej2-fm-toolbar-text: #ffffff;
--ej2-fm-selection-bg: #e3f2fd;
--ej2-fm-border: #e0e0e0;
--ej2-fm-hover-bg: #f5f5f5;
}
.e-filemanager {
--ej2-fm-hover-bg: #f0f4ff;
}Usage:
import React from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
import './styles/custom-theme.css';
function CustomTheme() {
return <FileManagerComponent {...props} />;
}
export default CustomTheme;Toolbar Customization
Configure Toolbar Items
import React from 'react';
import { FileManagerComponent, Inject, Toolbar } from '@syncfusion/ej2-react-filemanager';
function CustomToolbar() {
const toolbarSettings = {
items: [
'NewFolder',
'Upload',
'Delete',
'Download',
'Rename',
'SortBy',
'Refresh',
'Selection',
'View',
'Details'
]
};
return (
<FileManagerComponent
toolbarSettings={toolbarSettings}
ajaxSettings={{...}}
>
<Inject services={[Toolbar]} />
</FileManagerComponent>
);
}
export default CustomToolbar;Available Items:
- NewFolder, Upload, Delete, Download, Rename
- SortBy, Refresh, Selection, View, Details
- Custom items (see below)
Add Custom Toolbar Items
const toolbarSettings = {
items: [
'NewFolder',
'Upload',
{
name: 'Share',
text: 'Share',
icon: 'e-icons e-share',
id: 'share-btn'
},
'Delete',
'Download'
]
};
const handleToolbarClick = (args) => {
if (args.item.id === 'share-btn') {
console.log('Share button clicked');
// Open share dialog
}
};
<FileManagerComponent
toolbarSettings={toolbarSettings}
toolbarClick={handleToolbarClick}
ajaxSettings={{...}}
>
<Inject services={[Toolbar]} />
</FileManagerComponent>Context Menu Customization
Configure Context Menu Items
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane } from '@syncfusion/ej2-react-filemanager';
function CustomContextMenu() {
const contextMenuSettings = {
file: [
'Open',
'Edit',
'Download',
'Cut',
'Copy',
'Delete',
'Rename',
'Properties'
],
folder: [
'Open',
'Cut',
'Copy',
'Delete',
'Rename',
'NewFolder',
'Properties'
]
};
return (
<FileManagerComponent
contextMenuSettings={contextMenuSettings}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane]} />
</FileManagerComponent>
);
}
export default CustomContextMenu;Add Custom Menu Items
const contextMenuSettings = {
file: [
'Download',
'Cut',
'Copy',
'Delete',
{ text: 'Compress', id: 'compress' },
{ text: 'Encrypt', id: 'encrypt' }
]
};
const handleMenuClick = (args) => {
if (args.item.id === 'compress') {
console.log('Compress:', args.fileDetails);
// Call compress API
} else if (args.item.id === 'encrypt') {
console.log('Encrypt:', args.fileDetails);
// Call encrypt API
}
};
<FileManagerComponent
contextMenuSettings={contextMenuSettings}
menuClick={handleMenuClick}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane]} />
</FileManagerComponent>View Customization
Details View Settings
import React from 'react';
import { FileManagerComponent, Inject, DetailsView } from '@syncfusion/ej2-react-filemanager';
function CustomDetailsView() {
const detailsViewSettings = {
columns: [
{ field: 'name', headerText: 'Name', width: '200px' },
{ field: 'dateModified', headerText: 'Modified', width: '150px' },
{ field: 'size', headerText: 'Size', width: '100px' },
{ field: 'type', headerText: 'Type', width: '100px' }
]
};
return (
<FileManagerComponent
view="Details"
detailsViewSettings={detailsViewSettings}
ajaxSettings={{...}}
>
<Inject services={[DetailsView]} />
</FileManagerComponent>
);
}
export default CustomDetailsView;Navigation Pane Settings
const navigationPaneSettings = {
maxWidth: '300px',
minWidth: '150px',
expandedWidth: '250px'
};
<FileManagerComponent
navigationPaneSettings={navigationPaneSettings}
ajaxSettings={{...}}
>
<Inject services={[NavigationPane]} />
</FileManagerComponent>Complete Example
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
import '@syncfusion/ej2-react-filemanager/styles/material.css';
import './custom-theme.css';
function FullyCustomizedFileManager() {
const toolbarSettings = {
items: [
'NewFolder',
'Upload',
{ text: 'Archive', id: 'archive' },
{ text: 'Share', id: 'share' },
'Delete',
'Download',
'Refresh'
]
};
const contextMenuSettings = {
file: ['Download', 'Cut', 'Copy', 'Delete', { text: 'Compress', id: 'compress' }],
folder: ['Open', 'Cut', 'Copy', 'Delete', 'Rename']
};
const detailsViewSettings = {
columns: [
{ field: 'name', headerText: 'File Name', width: '300px' },
{ field: 'dateModified', headerText: 'Date Modified', width: '200px' },
{ field: 'size', headerText: 'File Size', width: '150px' }
]
};
const navigationPaneSettings = {
maxWidth: '350px'
};
const handleToolbarClick = (args) => {
if (args.item.id === 'archive') {
alert('Archive selected files');
} else if (args.item.id === 'share') {
alert('Share selected files');
}
};
const handleMenuClick = (args) => {
if (args.item.id === 'compress') {
alert('Compress: ' + args.fileDetails[0].name);
}
};
return (
<FileManagerComponent
view="Details"
sortBy="name"
sortOrder="Ascending"
toolbarSettings={toolbarSettings}
contextMenuSettings={contextMenuSettings}
detailsViewSettings={detailsViewSettings}
navigationPaneSettings={navigationPaneSettings}
toolbarClick={handleToolbarClick}
menuClick={handleMenuClick}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
height="700px"
cssClass="custom-file-manager"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default FullyCustomizedFileManager;Common Patterns
Dark Theme
:root {
--ej2-fm-bg: #1e1e1e;
--ej2-fm-text: #ffffff;
--ej2-fm-toolbar-bg: #2d2d2d;
--ej2-fm-border: #404040;
--ej2-fm-hover-bg: #3a3a3a;
}
.dark-mode .e-filemanager {
background: var(--ej2-fm-bg);
color: var(--ej2-fm-text);
}Compact View
const compactSettings = {
detailsViewSettings: {
columns: [
{ field: 'name', headerText: 'Name', width: '250px' },
{ field: 'size', headerText: 'Size', width: '80px' }
]
},
navigationPaneSettings: {
maxWidth: '200px'
},
height: '400px'
};Mobile-Responsive
<FileManagerComponent
view={window.innerWidth < 768 ? 'LargeIcons' : 'Details'}
navigationPaneSettings={{
maxWidth: window.innerWidth < 768 ? '150px' : '250px'
}}
height={window.innerHeight - 100 + 'px'}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Next Steps
- Drag-and-Drop: Master drag operations in drag-and-drop.md
- Accessibility: WCAG compliance in accessibility-localization.md
- Advanced: Performance and custom providers in advanced-features.md
Customize Custom Thumbnail in React File Manager
The React File Manager component allows you to customize thumbnails and icons displayed for files and folders using the showThumbnail property and custom templates. This enables you to display custom icons or images based on file types or specific requirements.
Table of Contents
1. Basic Thumbnail Customization 2. Advanced Thumbnail Customization 3. Custom Thumbnail Properties 4. Icon Sources 5. Best Practices 6. Related Topics
Basic Thumbnail Customization
Pattern 1: Hide Thumbnails
By default, thumbnails are shown. You can disable them using the showThumbnail property:
import React from 'react';
import { FileManagerComponent, Inject, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function HideThumbnailExample() {
return (
<FileManagerComponent
id="file-manager"
height="500px"
showThumbnail={false} // Disable thumbnail display
ajaxSettings={{
url: "url",
downloadUrl: "url",
uploadUrl: "url",
getImageUrl: "url"
}}
>
<Inject services={[NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default HideThumbnailExample;Pattern 2: Show Thumbnails (Default)
<FileManagerComponent
showThumbnail={true} // Enable thumbnail display
// ... other properties
/>Advanced Thumbnail Customization
Pattern 1: Custom Template for Large Icons View
import React from 'react';
import { FileManagerComponent, Inject, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function CustomLargeIconTemplate() {
const largeIconsTemplate = (props) => {
const getFileIcon = (name) => {
const ext = name.split('.').pop().toLowerCase();
const iconMap = {
'pdf': '📄',
'doc': '📝',
'docx': '📝',
'xls': '📊',
'xlsx': '📊',
'ppt': '🎯',
'pptx': '🎯',
'txt': '📃',
'jpg': '🖼️',
'jpeg': '🖼️',
'png': '🖼️',
'gif': '🖼️',
'mp4': '🎬',
'mp3': '🎵',
'zip': '📦',
'rar': '📦',
};
return iconMap[ext] || '📁';
};
return (
<div className="e-large-icon-item" style={{
textAlign: 'center',
padding: '10px',
cursor: 'pointer'
}}>
<div style={{ fontSize: '48px', marginBottom: '8px' }}>
{props.isFile ? getFileIcon(props.name) : '📁'}
</div>
<div style={{
fontSize: '12px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
maxWidth: '100px'
}}>
{props.name}
</div>
</div>
);
};
return (
<FileManagerComponent
id="file-manager"
height="500px"
view="LargeIcons"
largeIconsTemplate={largeIconsTemplate}
ajaxSettings={{
url: "url",
downloadUrl: "url",
uploadUrl: "url",
getImageUrl: "url"
}}
>
<Inject services={[NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default CustomLargeIconTemplate;Pattern 2: File Type-Based Icons
function getCustomIcon(fileName) {
const fileType = fileName.split('.').pop().toLowerCase();
const iconClasses = {
// Documents
'pdf': 'e-icon-pdf',
'doc': 'e-icon-doc',
'docx': 'e-icon-doc',
'txt': 'e-icon-txt',
// Spreadsheets
'xls': 'e-icon-xls',
'xlsx': 'e-icon-xls',
'csv': 'e-icon-csv',
// Presentations
'ppt': 'e-icon-ppt',
'pptx': 'e-icon-ppt',
// Images
'jpg': 'e-icon-jpg',
'jpeg': 'e-icon-jpg',
'png': 'e-icon-png',
'gif': 'e-icon-gif',
'bmp': 'e-icon-bmp',
// Videos
'mp4': 'e-icon-video',
'avi': 'e-icon-video',
'mov': 'e-icon-video',
'mkv': 'e-icon-video',
// Audio
'mp3': 'e-icon-audio',
'wav': 'e-icon-audio',
'flac': 'e-icon-audio',
// Archives
'zip': 'e-icon-zip',
'rar': 'e-icon-zip',
'7z': 'e-icon-zip',
// Code
'js': 'e-icon-code',
'ts': 'e-icon-code',
'py': 'e-icon-code',
'java': 'e-icon-code',
'cpp': 'e-icon-code',
'html': 'e-icon-html',
'css': 'e-icon-css',
'json': 'e-icon-json',
'xml': 'e-icon-xml',
};
return iconClasses[fileType] || 'e-icon-default';
}Pattern 3: Size-Based Color Coding
function getThumbnailStyle(fileSize) {
let colorClass = 'thumbnail-small';
if (fileSize > 100 * 1024 * 1024) { // 100MB+
colorClass = 'thumbnail-large';
} else if (fileSize > 10 * 1024 * 1024) { // 10MB+
colorClass = 'thumbnail-medium';
}
return colorClass;
}
const styles = `
.thumbnail-small {
border: 2px solid green;
opacity: 0.8;
}
.thumbnail-medium {
border: 2px solid orange;
opacity: 0.8;
}
.thumbnail-large {
border: 2px solid red;
opacity: 0.8;
}
`;Pattern 4: Date-Based Icons (Recent/Archived)
function getDateBasedIcon(fileDate) {
const now = new Date();
const file = new Date(fileDate);
const diffDays = (now - file) / (1000 * 60 * 60 * 24);
if (diffDays < 1) {
return 'e-icon-new'; // New file (today)
} else if (diffDays < 7) {
return 'e-icon-recent'; // Recent file (this week)
} else if (diffDays > 365) {
return 'e-icon-archived'; // Archived file (older than 1 year)
} else {
return 'e-icon-default';
}
}Complete Example with Custom Thumbnails
import React from 'react';
import { FileManagerComponent, Inject, NavigationPane, DetailsView, Toolbar } from '@syncfusion/ej2-react-filemanager';
function AdvancedThumbnailCustomization() {
const hostUrl = "url";
const getFileIcon = (name) => {
const ext = name.split('.').pop().toLowerCase();
const iconMap = {
// Documents
'pdf': '📄', 'doc': '📝', 'docx': '📝', 'txt': '📃',
// Spreadsheets
'xls': '📊', 'xlsx': '📊', 'csv': '📊',
// Presentations
'ppt': '🎯', 'pptx': '🎯',
// Images
'jpg': '🖼️', 'jpeg': '🖼️', 'png': '🖼️', 'gif': '🖼️', 'bmp': '🖼️',
// Videos
'mp4': '🎬', 'avi': '🎬', 'mov': '🎬', 'mkv': '🎬',
// Audio
'mp3': '🎵', 'wav': '🎵', 'flac': '🎵',
// Archives
'zip': '📦', 'rar': '📦', '7z': '📦',
// Code
'js': '⚙️', 'ts': '⚙️', 'py': '🐍', 'java': '☕', 'html': '🌐', 'css': '🎨',
};
return iconMap[ext] || '📁';
};
const formatFileSize = (bytes) => {
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 Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
};
const largeIconsTemplate = (props) => {
const isRecent = (date) => {
const diff = (new Date() - new Date(date)) / (1000 * 60 * 60 * 24);
return diff < 1;
};
return (
<div className="e-large-icon-item" style={{
textAlign: 'center',
padding: '10px',
cursor: 'pointer',
borderRadius: '8px',
transition: 'all 0.3s ease',
}}>
<div style={{
fontSize: '48px',
marginBottom: '8px',
position: 'relative'
}}>
{props.isFile ? getFileIcon(props.name) : '📁'}
{isRecent(props.dateModified) && (
<span style={{
position: 'absolute',
top: '0',
right: '0',
backgroundColor: 'red',
color: 'white',
borderRadius: '50%',
width: '24px',
height: '24px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '12px',
fontWeight: 'bold'
}}>
🆕
</span>
)}
</div>
<div style={{
fontSize: '12px',
fontWeight: '500',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
maxWidth: '100px',
marginBottom: '4px'
}}>
{props.name}
</div>
{props.isFile && (
<div style={{
fontSize: '10px',
color: '#666'
}}>
{formatFileSize(props.size)}
</div>
)}
</div>
);
};
return (
<div className="control-section">
<FileManagerComponent
id="custom-thumbnail"
height="500px"
view="LargeIcons"
ajaxSettings={{
url: hostUrl + 'api/FileManager/FileOperations',
downloadUrl: hostUrl + 'api/FileManager/Download',
uploadUrl: hostUrl + 'api/FileManager/Upload',
getImageUrl: hostUrl + 'api/FileManager/GetImage'
}}
largeIconsTemplate={largeIconsTemplate}
showThumbnail={true}
>
<Inject services={[NavigationPane, DetailsView, Toolbar]} />
</FileManagerComponent>
<style>{`
.e-large-icon-item:hover {
background-color: #f5f5f5;
transform: scale(1.05);
}
`}</style>
</div>
);
}
export default AdvancedThumbnailCustomization;Custom Thumbnail Properties
| Property | Type | Description |
|---|---|---|
showThumbnail | boolean | Show/hide thumbnails |
largeIconsTemplate | Template | Custom template for large icons view |
detailsViewTemplate | Template | Custom template for details view |
Icon Sources
Built-in Syncfusion Icons
Use Syncfusion Material or Fabric icon classes:
const iconClasses = {
'e-icons e-file', // Generic file
'e-icons e-folder', // Folder
'e-icons e-file-pdf', // PDF
'e-icons e-file-xls', // Excel
'e-icons e-file-ppt', // PowerPoint
'e-icons e-file-image', // Image
'e-icons e-file-video', // Video
'e-icons e-file-audio', // Audio
'e-icons e-file-zip', // Archive
};Best Practices
1. Use Emoji or Icons Consistently - Choose either emoji or icon fonts 2. Maintain Visual Hierarchy - Use size and color to indicate importance 3. Show File Information - Display size, date, or other metadata 4. Optimize Performance - Cache icon mappings 5. Test Accessibility - Ensure icons are accompanied by text descriptions
Related Topics
- Customization
- Views and Navigation
- File Operations
- Getting Started
Drag-and-Drop Features
Master drag-and-drop functionality for moving files between folders and handling custom drop zones.
Table of Contents
1. Enable Drag-and-Drop 2. Drag-and-Drop Events 3. Drag-and-Drop Validation 4. Advanced Drag-and-Drop 5. Complete Example 6. Common Patterns 7. Edge Cases 8. Next Steps
Enable Drag-and-Drop
Basic Drag-and-Drop
Enable by default or explicitly configure:
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function DragDropExample() {
return (
<FileManagerComponent
allowDragAndDrop={true}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default DragDropExample;What Drag-Drop Enables:
- Drag files between folders
- Drag from file manager to other drop zones
- Visual feedback during drag
- Move operations (files are moved, not copied)
Drag-and-Drop Events
Handle Drag Start
import React, { useRef } from 'react';
import { FileManagerComponent } from '@syncfusion/ej2-react-filemanager';
function DragStartExample() {
const fileManagerRef = useRef(null);
const handleFileDragStart = (args) => {
console.log('Drag started:', args.fileDetails);
console.log('Source element:', args.target);
};
return (
<FileManagerComponent
ref={fileManagerRef}
fileDragStart={handleFileDragStart}
ajaxSettings={{...}}
allowDragAndDrop={true}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default DragStartExample;Available Events:
fileDragStart- Drag operation startsfileDragStop- Drag ends (drop or cancel)fileDropped- File successfully dropped
Handle File Drop
const handleFileDropped = (args) => {
console.log('Files dropped:', args.fileDetails);
console.log('Target path:', args.path);
// Validate drop operation
if (args.path.includes('/restricted')) {
args.cancel = true;
console.error('Cannot drop in restricted folder');
}
};
<FileManagerComponent
fileDropped={handleFileDropped}
ajaxSettings={{...}}
allowDragAndDrop={true}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Handle Drag Stop
const handleFileDragStop = (args) => {
console.log('Drag ended');
console.log('Drop cancelled:', args.cancel);
};
<FileManagerComponent
fileDragStop={handleFileDragStop}
ajaxSettings={{...}}
allowDragAndDrop={true}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Drag-and-Drop Validation
Prevent Drag of Specific Files
const handleFileDragStart = (args) => {
const restrictedExtensions = ['.exe', '.bat', '.cmd'];
args.fileDetails.forEach(file => {
const ext = '.' + file.name.split('.').pop().toLowerCase();
if (restrictedExtensions.includes(ext)) {
args.cancel = true;
console.error(`Cannot drag ${ext} files`);
}
});
};
<FileManagerComponent
fileDragStart={handleFileDragStart}
allowDragAndDrop={true}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Prevent Drop in Specific Folders
const handleFileDropped = (args) => {
const restrictedPaths = ['/System', '/bin', '/root'];
if (restrictedPaths.some(path => args.path.startsWith(path))) {
args.cancel = true;
console.error('Cannot drop in protected folders');
}
};
<FileManagerComponent
fileDropped={handleFileDropped}
allowDragAndDrop={true}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Advanced Drag-and-Drop
Drag Multiple Files
const handleFileDragStart = (args) => {
const fileCount = args.fileDetails.length;
const totalSize = args.fileDetails.reduce((sum, f) => sum + f.size, 0);
console.log(`Dragging ${fileCount} files, ${totalSize} bytes`);
// Validate total size
const maxTotalSize = 500 * 1024 * 1024; // 500 MB
if (totalSize > maxTotalSize) {
args.cancel = true;
console.error('Total drag size exceeds limit');
}
};
<FileManagerComponent
fileDragStart={handleFileDragStart}
allowMultiSelection={true}
allowDragAndDrop={true}
ajaxSettings={{...}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Drag from External Sources
Allow dragging files from file explorer into File Manager:
<FileManagerComponent
allowDragAndDrop={true}
ajaxSettings={{
url: "url",
uploadUrl: "url",
getImageUrl: "url",
downloadUrl: "url"
}}
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>Behavior:
- Drag files from OS file explorer
- Drop into File Manager
- Automatically uploads via
uploadUrl - Same validation as manual upload applies
Complete Example
import React from 'react';
import { FileManagerComponent, Inject, DetailsView, NavigationPane, Toolbar } from '@syncfusion/ej2-react-filemanager';
function AdvancedDragDrop() {
const handleFileDragStart = (args) => {
console.log('Drag started:', args.fileDetails.length, 'files');
};
const handleFileDragStop = (args) => {
console.log('Drag stopped');
};
const handleFileDropped = (args) => {
console.log('Dropped at:', args.path);
// Validate before drop
const protectedFolders = ['/System', '/Admin'];
if (protectedFolders.some(f => args.path.startsWith(f))) {
args.cancel = true;
alert('Cannot drop in protected folders');
}
};
return (
<FileManagerComponent
allowDragAndDrop={true}
allowMultiSelection={true}
fileDragStart={handleFileDragStart}
fileDragStop={handleFileDragStop}
fileDropped={handleFileDropped}
ajaxSettings={{
url: "url",
getImageUrl: "url",
uploadUrl: "url",
downloadUrl: "url"
}}
height="600px"
>
<Inject services={[DetailsView, NavigationPane, Toolbar]} />
</FileManagerComponent>
);
}
export default AdvancedDragDrop;Common Patterns
Drag with Permission Check
const handleFileDropped = (args) => {
const userPermissions = ['Documents', 'Downloads'];
if (!userPermissions.some(p => args.path.includes(p))) {
args.cancel = true;
alert('You do not have permission to drop here');
}
};Drag with Size Validation
const handleFileDragStart = (args) => {
const maxDragSize = 1024 * 1024 * 1024; // 1 GB
const totalSize = args.fileDetails.reduce((sum, f) => sum + f.size, 0);
if (totalSize > maxDragSize) {
args.cancel = true;
alert('Cannot drag files exceeding 1 GB');
}
};Edge Cases
Issue: Drag-drop doesn't work
- Verify
allowDragAndDrop={true} - Check browser console for errors
- Ensure drop target is valid
Issue: Files duplicate on drop
- Verify backend move operation (not copy)
- Check if
fileDroppedevent hasargs.cancel = true
Issue: Large file drag is slow
- Consider showing progress indicator
- Implement backend optimization
- Use virtual scrolling for large file lists
Next Steps
- Customization: Style and customize in customization.md
- File Operations: Learn CRUD operations in file-operations.md
- Advanced: Performance tips in advanced-features.md
Related skills
How it compares
Choose syncfusion-react-file-manager over generic React file-upload snippets when you need a full explorer UI with Syncfusion APIs, theming, and enterprise file operations.
FAQ
What Syncfusion version does syncfusion-react-file-manager document?
syncfusion-react-file-manager metadata lists Syncfusion React File Manager version 33.1.44. The skill routes common tasks to 39 reference guides covering setup, CRUD, virtualization, customization, and accessibility.
Can syncfusion-react-file-manager handle remote storage backends?
syncfusion-react-file-manager documents local flat data and remote provider patterns, including passing custom headers for authenticated APIs and role-based access control for user permissions on file operations.