Progressive-enhancement file browser. You write the full HTML structure once;
wf-file-manager.js
queries those elements and wires up all interactivity. A live read-only demo below lets you explore all three view modes, the preview panel, filtering, sorting, and breadcrumb navigation against a real demo folder.
Key capabilities:
Three view modes -
thumbnail grid
,
list
, and
table
- persisted in
localStorage
Drag-and-drop and click-to-select upload with per-file
XMLHttpRequest
progress bars
Inline folder creation and multi-file deletion
Breadcrumb navigation for subfolder traversal
Collapsible preview panel with file metadata, persisted in
localStorage
Sidebar filter by file type and sort control
Live Demo
Fully functional file manager running against a read-only demo folder. Browse, filter, sort, switch view modes and open the preview panel. Upload and delete actions return simulated responses — no files are modified.
Demo mode — uploads and deletions are simulated. The demo folder is read-only.
Required Markup
The component expects a root element marked with
data-wf-file-manager
and
data-wf-url
. All child elements below must be present before the script initialises — the JS fills dynamic content only (breadcrumbs, file grid, upload rows, preview data).
Minimal complete structure. Omit or reorder sections to match your layout.
WojoFileSelect wrapper around the file <input> — the trigger button is injected automatically
No
.wf-fm-folder-wrap
Wrapper for folder-name input + add button
No
.wf-fm-folder-name
Folder-name <input>
No
.wf-fm-folder-add
“New folder” <button>
No
.wf-fm-del-btn
Delete selected <button>
No
.wf-fm-view-btns
View-mode button group wrapper
No
.wf-fm-view-btn[data-view]
View-mode toggles — values: thumb, list, table
No
.wf-fm-preview-toggle
Preview-panel show/hide <button>
No
.wf-fm-filter-nav
Sidebar filter list container
No
.wf-fm-filter-item[data-filter]
Filter items — values: all, pic, vid, aud, doc
No
.wf-fm-sort-wrap
Sort label + select wrapper
No
.wf-fm-sort-sel
Sort <select>
No
.wf-fm-breadcrumbs
Breadcrumb navigation trail
Yes
.wf-fm-upload-list
Upload progress rows container
Yes
.wf-fm-grid
File/folder card container
Yes
.wf-fm-preview
Preview panel <aside>
—
.wf-fm-preview-thumb
Preview thumbnail area
Yes
.wf-fm-preview-meta
Preview file metadata area
Yes
[data-stat]
Footer stat labels — values: count, size, selected
Yes
Show More
View Modes
Three view modes are toggled by the
.wf-fm-view-btn[data-view]
buttons. The active mode is persisted to
localStorage
under the key
wf-fm-view
, so the user’s preference survives page reloads. The active button receives
wf-active
, and the grid container gets the corresponding modifier class.
Mode
data-view
Grid class applied
Description
Thumbnail Grid
thumb
wf-fm-thumb-grid
Autofill grid of square thumbnail cards. Min card width controlled by --wf-fm-thumb-min (default 116px).
List
list
wf-fm-list-grid
Compact single-column rows with icon, name, size, and date.
Table
table
wf-fm-table-grid
Full-width table with columns: name, type, size, and modified date.
Upload
Upload is handled by two mechanisms: the standard file-input inside
.wf-fm-file-wrap
(enhanced by WojoFileSelect) and drag-and-drop directly onto the file grid. Both paths use
XMLHttpRequest
with a
progress
event, so each file gets its own progress bar row in
.wf-fm-upload-list
.
Files are
POST
ed to the URL supplied in
data-wf-url
with
action=upload
. The file field name is
file
and the current path is sent as
path
so the server can place the file in the correct directory. On success the component fires
wf:fm-upload
and refreshes the directory listing.
Total component height. Also, settable via data-wf-height.
--wf-fm-sidebar-width
164px
Width of the left filter sidebar.
--wf-fm-preview-width
200px
Width of the right preview panel.
--wf-fm-thumb-min
116px
Minimum card width in thumbnail grid mode. The grid uses auto-fill so more cards fit on wider screens.
API Endpoint
All communication goes to the single URL you supply in
data-wf-url
. The
action
parameter tells the server what to do. All error responses should return
{ "ok": false, "message": "..." }
; the component will display the
message
string in the UI.
After initialization the instance is stored on the root element as
el._wfFileManager
.
JS
const root = document.querySelector('[data-wf-file-manager]')
const fm = root._wfFileManager
fm.navigate('images/avatars') // open a sub-folder
fm.refresh() // reload current directory
fm.destroy() // remove all event listeners
Method
Signature
Description
navigate()
navigate(path: string)
Navigate to a specific subfolder path. Updates breadcrumbs and reloads the grid.
refresh()
refresh()
Reload the current directory from the API without changing the path.
destroy()
destroy()
Remove all event listeners registered by the component.
Events
All events bubble and are dispatched on the root
.wf-fm
element. Listen from any ancestor with
addEventListener
.
JS
document.addEventListener('wf:fm-upload', e => {
console.log('Uploaded:', e.detail.file.name, e.detail.data)
})
document.addEventListener('wf:fm-delete', e => {
console.log('Deleted paths:', e.detail.paths)
})
document.addEventListener('wf:fm-folder', e => {
console.log('Folder created:', e.detail.name)
})
document.addEventListener('wf:fm-select', e => {
console.log('Selected file:', e.detail.file)
})
Event
detail
Fired when
wf:fm-upload
{ file, data }
A file upload completes successfully. file is the native File object; data is the server response.
wf:fm-delete
{ paths }
Selected files/folders are deleted. paths is an array of relative path strings.
wf:fm-folder
{ name }
A new folder is created. name is the folder name string.
wf:fm-select
{ file }
A file card is selected in the grid. file is the file descriptor object from the API response.
Class Reference
Class
Description
wf-fm
Root component element. Hosts all CSS custom properties and layout context.
wf-fm-toolbar
The top toolbar row contains upload, folder, delete, view-mode, and preview controls.
wf-fm-file-wrap
Wrapper for the upload <input type="file">. Enhanced by WojoFileSelect to add drag-and-drop.
wf-fm-folder-name
Text input for the new-folder name.
wf-fm-folder-add
Button that submits the new-folder request.
wf-fm-del-btn
Button that deletes all currently selected items.
wf-fm-view-btn
View-mode toggle button. Receives wf-active on the current mode. Requires data-view (thumb · list ·
table).
wf-fm-preview-toggle
Button that shows or hides the preview panel.
wf-fm-body
Flex container holding the sidebar, main panel, and preview panel.
wf-fm-sidebar
Left sidebar with filter navigation and sort select.
wf-fm-filter-nav
List container for filter items.
wf-fm-filter-item
Individual filter items. Receives wf-active when selected. Requires data-filter (all · pic · vid
· aud · doc).
Main content area holding breadcrumbs, upload list, and file grid.
wf-fm-breadcrumbs
Breadcrumb navigation trail. Populated by JS on each navigation.
wf-fm-upload-list
Container for per-file upload progress rows appended by JS during upload.
wf-fm-grid
File-card container. Gets one of three modifier classes depending on the active view mode.
wf-fm-thumb-grid
Applied to .wf-fm-grid in thumbnail view. Uses CSS auto-fill grid.
wf-fm-list-grid
Applied to .wf-fm-grid in list view. Single-column layout.
wf-fm-table-grid
Applied to .wf-fm-grid in table view. Full-width table layout.
wf-fm-item
Individual file or folder card. Receives wf-selected when checked. Modifier wf-fm-item--dir for folders; wf-fm-item--[type] for file type coloring (pic · vid · aud ·
doc).
wf-fm-preview
Right-side preview panel <aside>. Hidden when preview is off.
wf-fm-preview-thumb
Thumbnail/icon area inside the preview panel. Populated by JS on selection.
wf-fm-preview-meta
File metadata area inside the preview panel (name, size, type, date). Populated by JS.
wf-fm-footer
Footer bar. Contains [data-stat="files"], [data-stat="dirs"], and [data-stat="space"] spans updated by JS.