File Manager
alphav0.1.3Finder-style file browser — grid and list views, marquee multi-select, cut copy paste, drag-and-drop, and a shared clipboard primitive.
Context
Pairs with `file-tree` (the sidebar primitive) for the dual-pane Finder layout — drop `<FileTree>` into `<FileManager>`'s `sidebar` slot. Use anywhere a current-folder content view is needed: asset libraries, document workspaces, attachment managers, S3-bucket explorers. Controlled-data, object-shape callbacks, lazy children. The new `<FileClipboardProvider>` syncs cut/copy/paste across multiple instances.
Installation
pnpm dlx shadcn@latest init"registries": {
"@ilinxa": "https://ui.ilinxa.com/r/{name}.json"
}pnpm dlx shadcn@latest add @ilinxa/file-managerAdd -fixtures for dummy data:
pnpm dlx shadcn@latest add @ilinxa/file-manager-fixturesPreview
Demo source
Usage
When to use
FileManager is the Mac-Finder content pane: a grid / list view of the current folder with multi-select, cut / copy / paste, drag-and-drop, sort, and view-mode switching. Pair it with file-tree in the sidebar slot for the dual-pane Finder layout. Standalone use is also supported.
Data shape
Same FsNode shape as file-tree — id / name / type / parentId / children / ext / size / modifiedAt / icon / meta. Consumer owns nodes and currentFolderId; manager fires object-shape callbacks on every operation.
Shared clipboard
Wrap one or more <FileManager> instances in <FileClipboardProvider> to sync cut / copy / paste across instances. Without a provider, each manager keeps its own internal clipboard. Controlled mode: pass clipboard + onClipboardChange.
import { FileManager, FileClipboardProvider } from "@/components/file-manager"
<FileClipboardProvider>
<FileManager nodes={nodes} sidebar={<FileTree nodes={nodes} />} />
</FileClipboardProvider>Lazy loading
import { mergeLoadedChildren } from "@/components/file-manager"
<FileManager
nodes={nodes}
currentFolderId={current}
onCurrentFolderChange={({ folderId }) => setCurrent(folderId)}
onLoadChildren={async ({ nodeId }) => {
const kids = await fs.list(nodeId);
setNodes((prev) => mergeLoadedChildren(prev, nodeId, kids));
return kids;
}}
/>Keyboard map
- Arrow keys move focus (2-D nav in grid mode, up/down only in list mode).
- Enter opens a file (
onOpen) or navigates into a folder. - Backspace deletes selected items (with confirm), or navigates up to parent if no selection.
- F2 renames; Delete deletes; Esc clears selection or cancels rename.
- Cmd/Ctrl+X / C / V cut / copy / paste; Cmd/Ctrl+A select all visible.
- Cmd/Ctrl+[ back; Cmd/Ctrl+] forward.
- Type-ahead: typing letters jumps focus to the first matching item name (resets after 800ms).
Drag-and-drop
- Within the manager: drag selected items onto a folder. Cycle / self-drop refused; drops on files are rejected (only folders are valid targets).
- From the desktop: drop OS files onto the manager to fire
onExternalDrop.targetFolderIdis the folder the user dropped on, or the current folder otherwise. - Marquee selection: drag a rectangle on empty space to select multiple items. Shift+drag adds to existing selection.
Custom chrome
Replace the toolbar via renderToolbar (typed context), or compose the standalone parts: FileManagerToolbar,FileManagerPathBar, FileManagerViewToggle,FileManagerIconSizeControl, FileManagerSortMenu, FileManagerSearchInput, FileManagerStatusBar. They read from useFileManager().
Gotchas
- Drops on files are rejected; only folders accept drops. Drops on empty whitespace are no-ops for internal drag, upload-to-current for external drag.
- Selection clears on navigate by default. Set
preserveSelectionOnNavigate={true}to keep it. - Cut / copy / paste require
onPastewired. Without a paste handler, the manager firesonClipboardChangebut paste does nothing. - Dragging files OUT to the desktop is not supported in v0.1.0. Add a Download button via
renderContextMenuor the toolbar overflow. - List-view virtualizes at
virtualizeThresholditems (default 200). Grid view does NOT virtualize at v0.1.0.
Features
- Grid + list view modes with three icon sizes (sm/md/lg) in grid mode
- Path bar / breadcrumbs with click-to-edit text input mode
- Back / Forward / Up navigation with built-in 50-entry history (controllable bypass)
- Multi-select with Cmd/Ctrl+click, Shift+click range, Cmd/Ctrl+A, plus marquee (drag-rectangle)
- Cut / copy / paste backed by a shared `<FileClipboardProvider>` primitive
- Right-click menu (Open / New / Cut / Copy / Paste / Rename / Delete / Refresh) with `renderContextMenu` slot
- Inline rename via F2 / double-click; optional `validateRename`
- Drag-and-drop within the manager (move) + drag-from-OS (`onExternalDrop`)
- Cycle / self-drop pre-validation; only folders are valid drop targets
- Lazy children loading via `onLoadChildren` + exported `mergeLoadedChildren` helper
- Built-in sort menu (Name / Modified / Size / Type, asc/desc) + sortable list-view headers
- Search input filtering current folder by name (case-insensitive substring)
- Type-ahead select (typing letters jumps focus to matching name)
- Status bar (item count / selected / total size); replaceable via `renderStatusBar`
- Sidebar + details slots for dual-pane / preview compositions
- List-view virtualization at >=200 items via TanStack Virtual
- Object-shape callbacks (F-cross-12-correct from day one)
- WCAG 2.1 AA — `role=grid`, `aria-multiselectable`, roving tabindex, live-region announcements