File manager

Enterprise file-browser composed from mp-splitter, mp-treeview, and mp-datatable Lit web components. Tree on the left, file list on the right, breadcrumb above, toolbar with search, view-mode toggle, and file operations. The live demo below is fully interactive: drag-drop files from your OS, rename inline, multi-select, cut/copy/paste, switch the language, simulate read-only permissions, or toggle on the lazy-load tree mode.

Allow drag-drop upload
Use custom dialog resolver
Prompt on name conflict
"Documents" read-only
Lazy-load tree
Keyboard shortcuts
  • / — move row focus within the file list
  • Enter on a folder — navigate into it; on a file — open
  • Ctrl+click — toggle a row in the selection
  • Shift+click — range-select between anchor and clicked row
  • F2 — rename selected item
  • Del — delete selection (with confirmation)
  • Ctrl+X / Ctrl+C / Ctrl+V — cut / copy / paste
  • Ctrl+Shift+N — new folder in current location
  • Shift+F10 / ContextMenu — open the context menu
  • Long-press (600 ms) on touch — opens the context menu

Integration guide for B2B portals

The component is intentionally event-driven: it renders the UX and emits intents, leaving every consumer to wire the backend, dialog style, and toast system of their own product. The recipes below cover the seven integration points a typical admin portal needs.

1. Operation handler (rename / delete / new folder / paste)

Every mutating action fires (operation) with a discriminated-union payload. The component is fire-and-forget — your handler runs the backend call, optionally marks the affected rows as pending, and reports failures through reportError() (which re-fires (errorReported) for your toast bus).

        
    

2. Upload pipeline with progress

Drag-drop and the touch upload button both fire (uploadRequest) carrying pre-registered UploadEntry IDs. Drive your real upload (XHR / fetch / S3 SDK), then push percentage updates into the component via reportUploadProgress(id, pct, status?). The uploads signal on the component reflects the in-flight set so you can render a progress UI wherever you like (the live demo above renders it directly below the file-manager).

        
    

3. Custom dialogs (replacing window.confirm / window.prompt)

Most enterprise apps want their own modal styling instead of the browser dialogs. Wire a DialogResolver to your modal service (typically a thin wrapper around bs-modal). When unset, the component falls back to the native dialogs so basic usage still works.

        
    

4. Conflict resolution on paste / upload

When a paste or upload would overwrite a same-name entry in the target folder, the component calls conflictResolver once per conflict. Returning 'skip' filters the source out of the operation; 'rename' includes the consumer's chosen newName in the resulting (operation) / (uploadRequest) payload. Unset = silent replace (preserves the v1 behaviour).

        
    

5. Lazy-loaded tree

Real file systems aren't materialisable up front. Bind a loadChildren async callback and seed [nodes] with only the top-level entries. The component marks every unloaded folder with a chevron, shows a spinner during the fetch, and merges the returned children back into its store — no consumer-side coordination beyond returning the right data.

        
    

6. Internationalisation

Every visible string + ARIA label routes through FileManagerMessages. Pass a partial overrides object via [messages]; unset keys fall back to DEFAULT_FILE_MANAGER_MESSAGES (English). Locale switching works at runtime — the demo above uses three locales.

        
    

7. Per-node permissions

Beyond the global [allowOperations] input, every FileSystemNode can carry its own allowOperations partial. The toolbar / context-menu buttons gate against the worst case across the current selection (a multi-row delete is disabled if any selected row is locked).

        
    

8. Error reporting → toast bus

Failures from your backend never need to reach into the component's UI directly. Call fm.reportError(message, nodeId?) from your handler and listen on (errorReported) at the template level — that's where you wire the toast / snackbar.

        
    

Checklist for production

  • Backend wiring — handle every kind in onOperation + the upload pipeline.
  • Toasts — listen on (errorReported); route to your snackbar.
  • Dialogs — wire dialogResolver to bs-modal if you don't want native browser dialogs.
  • Conflicts — wire conflictResolver if "silent overwrite" isn't your spec.
  • Permissions — surface per-node allowOperations from your auth layer.
  • i18n — pipe your translation service through [messages].
  • Scale — bind [loadChildren] if folder cardinality is unbounded.
  • Touch — no extra wiring; long-press + upload button activate automatically on coarse pointers.