File List Icon View

Finder's icon view: big icons and thumbnails in a grid, with date groups, drag to select and drag to move.

@cupertinoui-pro/file-list-icon-viewCupertinoUI Pro

Installation

pnpm dlx shadcn@latest add @cupertinoui-pro/file-list-icon-view

Part of CupertinoUI Pro: the CLI installs it with your license key, once the @cupertinoui-pro registry is in components.json.

Usage

import { FileListIconView } from "@/components/ui/file-list-icon-view"
import type { FileNode } from "@/lib/file-tree"

const files: FileNode[] = [
  { name: "Projects", children: [] },
  { name: "Wallpaper.webp", thumbnail: "/wallpaper.webp" },
]

<FileListIconView files={files} onFilesChange={setFiles} onOpen={openFile} />
files is the same JSON as FileListTable and FileListColumns take, so one tree can switch views. The icon view shows one folder: double-click a folder (or ⌘↓) to go into it and ⌘↑ to go back out; folder and onFolderChange control which one.
Files with a thumbnail show the image, scaled to fit the 64px icon; others show renderIcon. Names wrap onto two lines like Finder's, breaking after spaces and hyphens, and long ones are shortened in the middle so the extension stays visible.
Drag over empty space to select every item the rectangle touches; with Shift or ⌘ held it adds and removes. Click selects, Shift-click a range and ⌘-click single items. The arrow keys move around the grid, up and down by row, also across groups.
With onFilesChange, drag the selection onto a folder to move it, and right-click for Finder's menu: Open, Move to Trash, Rename, Duplicate, Copy and the tags; on empty space, New Folder. Return renames, ⌘D duplicates, ⇧⌘N makes a folder and ⌘⌫ deletes.
With groupBy, each group gets a sticky header; the one at the top gets the toolbar's background. A group longer than a row can be collapsed to its first row with Show Less.

Examples

Groups

groupBy puts the files under sticky headers, like Finder's Use Groups. A group longer than a row can show just its first row.

API Reference

Every part forwards the props of the underlying element. The props below are the ones CupertinoUI adds or changes.

FileNode

One file or folder in files: plain JSON, the same for every file list. Import the type from @/lib/file-tree.

PropTypeDescription
namestringThe file name.
idstringUnique among its siblings, for keys; defaults to the name. Can't contain "/".
childrenFileNode[]Makes it a folder; folders nest to any depth. Use [] for an empty folder.
thumbnailstringAn image URL shown instead of the icon in the icon and gallery views, and as the preview.
kind / size / created / modifiedstringShown as they are, so format them the way you want them displayed.
infoRecord<string, string>More Information rows for the column and gallery previews, e.g. { Dimensions: "2007×2853" }.
iconstringA hint for renderIcon, e.g. "image" or "movie".
tagstringA Finder tag color: "red", "orange", "yellow", "green", "blue", "purple" or "gray".
onOpen(file: FileNode) => voidCalled when this file or folder is opened: double-clicked, or ⌘O.

FileListIconView

PropTypeDescription
filesFileNode[]The tree. The view shows one folder of it at a time.
defaultFolderstring | null
Default: null
The key of the folder shown first; null is the top of the tree.
folderstring | nullThe folder shown, controlled. Update it from onFolderChange.
onFolderChange(folder: string | null) => voidCalled when a folder is opened, or ⌘↑ goes back up.
multipleboolean
Default: true
Lets people select several files, in a rectangle or with Shift and ⌘. false allows one.
defaultSelected / selectedstring[]The keys of the selected files, uncontrolled or controlled.
onSelectedChange(keys: string[], files: FileNode[]) => voidCalled when the selection changes.
renderIcon(file: FileNode) => ReactNodeThe icon of a file without a thumbnail, drawn 64px large. Defaults to a folder or a document.
onFilesChange(files: FileNode[], change: FileChange) => voidTurns on editing: moving, Move to Trash, Rename, Duplicate, New Folder and tags. Gets the new tree to store, and what changed.
onOpen(file: FileNode, key: string) => voidCalled when a file is opened: double-clicked, or ⌘O or ⌘↓. Folders open in the view.
menuItems(files: FileNode[], keys: string[]) => ReactNodeMore ContextMenuItems for the right-click menu, after Finder's own.
groupBy(file: FileNode) => stringPuts each file under a header with this name; groups come in the order of their first file.
classNamestringExtra classes, merged with the component's own.