Skip to content

DesktopIcons

DesktopIcons renders a column of file-style shortcuts on the right edge of the desktop. Each shortcut maps to a system window whose appearsAsDesktopIcon predicate currently returns true. The library subscribes to storage change events so the column updates without polling.

Add an entry from Hello to make the Recents folder appear Open in new tab ↗
import {
DesktopIcons,
registerSystemWindow,
type SystemWindowDef,
} from "@react-ui-os/desktop";

None. The component reads from the registered system window list and the active storage adapter.

registerSystemWindow("downloads", {
name: "Downloads",
accent: "#7c66f5",
defaultBounds: { w: 560, h: 420 },
content: DownloadsFolder,
appearsAsDesktopIcon: (storage) => hasDownloads(storage),
});

The fields that control desktop-icon behavior:

FieldTypeDescription
appearsAsDesktopIconboolean | ((storage: StorageAdapter) => boolean)false (default) hides the icon. true always shows it. A function is the state-earned pattern: evaluated on each storage change.
desktopIconComponentType<{ size?: number }>The icon painted on the shortcut. Defaults to a generic folder SVG.

The library follows the rule: a folder icon should not exist until the user has put something in it. Same shape a maker tool uses for Downloads and Presets:

registerSystemWindow("downloads", {
name: "Downloads",
defaultBounds: { w: 560, h: 420 },
content: DownloadsFolder,
appearsAsDesktopIcon: (storage) => listDownloads(storage).length > 0,
});
  • The first time recordDownload(...) writes to storage, the icon fades in.
  • When the last entry is deleted, it fades out.
  • The desktop never shows an empty-state pane for it, because the surface whose empty state you would design isn’t there yet.

The column mirrors the macOS desktop selection model (the same one FileExplorer uses) and is an ARIA multi-select listbox (role="listbox" with aria-multiselectable, role="option" with aria-selected), so the whole column is one tab stop and assistive tech announces the active icon.

Gesture / keyEffect
Single clickSelects the icon (accent highlight)
Cmd / Ctrl clickToggles the icon in the selection
Shift clickExtends the selection from the active icon
Double click / EnterOpens the matching system window via openWindow({ kind: "system", systemId })
Right clickSelects the icon and opens its context menu (Open)
ArrowUp / ArrowDownMoves the selection within the column
Home / EndSelects the first / last icon
Cmd / Ctrl + ASelects every icon
Escape / click offClears the selection

A left drag that starts on the bare desktop (off any window, the dock, the menu bar, or an icon) sweeps a rubber-band rectangle and selects the icons it covers, the way macOS, Windows, and GNOME all do. Hold Shift, Cmd, or Ctrl as the drag starts to add the sweep to the current selection rather than replace it. Press Escape, or the right mouse button, mid-sweep to cancel it and restore the previous selection. After a sweep that selected something, keyboard focus lands on the column so the arrow keys work right away.

DesktopIcons reserves the upper-right edge, below the menu bar when present. Stacked vertically with 18 px gaps between tiles.