Collection boardPro
Folders and boards for generated images: drag one image or a whole selection onto a board, multi select with the keys people already know, and act on the selection from a bulk bar with Undo.
On this page
Installation
Usage
import { CollectionBoard } from "@/components/ui/chatcn/pro/collection-board"
<CollectionBoard
images={images}
boards={boards}
onBoardsChange={setBoards}
folders={folders}
onDownload={(ids) => openExport(ids)}
onDelete={(ids) => api.deleteImages(ids)}
/>The sidebar lists All generations, then folders of boards, then loose boards and New board. Drag a tile past 6 px and it becomes a stack with a count that follows the pointer; the board under it lights up and the stack names where it will land. Dropping on New board makes a board with those images and opens its name for editing. Esc cancels a drag.
Drag is a shortcut, never the only way: the bulk bar's Add to board menu does the same from the keyboard and on touch, where tiles scroll instead of dragging. Removing images from a board and deleting them from the library both wait out an Undo window (undoMs, default 6 s); onDelete runs only when it closes.
Examples
States
Loading keeps the layout with quiet placeholders. An empty board says how to fill it. Long names truncate with the full name on hover, and the counts never truncate. Narrow containers turn the sidebar into one scrolling row of boards.
Props
| Prop | Type | Notes |
|---|---|---|
images | CollectionImage[] | Required. The whole library, newest first |
boards, defaultBoards, onBoardsChange | CollectionBoard[] | id, name, folderId, imageIds |
folders | CollectionFolder[] | Group boards in the sidebar |
activeId, defaultActiveId, onActiveChange | string | "all" shows every image |
selectedIds, defaultSelectedIds, onSelectedChange | string[] | |
onOpen | (image) => void | Enter or a double click |
onDownload | (ids) => void | Shows Download in the bulk bar |
onDelete | (ids) => void | Shows Delete in All generations, after Undo closes |
onAddToBoard | (boardId, ids) => void | After a drop or the menu |
loading | boolean | Skeleton sidebar and tiles |
allLabel | string | Default "All generations" |
undoMs | number | Default 6000 |
Keyboard
| Key | Action |
|---|---|
← → ↑ ↓, Home, End | Move through the grid |
Space | Select or clear the focused image |
Shift + arrow | Extend the selection |
⌘ or Ctrl + A | Select every image on the board |
Enter | Open the focused image |
Delete, Backspace | Remove from the board, or delete in All generations |
Esc | Clear the selection, or cancel a drag |
F2 on a board | Rename it |
Accessibility
- The grid is a multi select listbox with one tab stop; each tile is an option named by its alt text.
- Boards are buttons named by their visible name and count, with
aria-currenton the open one. - The bulk bar is a toolbar named by the selection count. Its labels collapse to icons in narrow containers and stay as the accessible names.
- Drops, menu adds, removals and Undo are announced in a polite live region.
Motion
- A selected image insets to 0.88 in 150 ms, so selection reads without color; from the keyboard it changes at once.
- The drag stack tracks the pointer 1:1 on transform and never eases its position. A board that received images swaps its count for a check for a moment.
- The bulk bar and Undo rise 8 px with a 180 ms fade. Reduced motion keeps only the fades.