Folder Shelf

@sushindustries/ui

A desktop of folders that open into draggable windows, several at once, remembered between visits.

8 min read
View as Markdown

The desktop on the home page is this, fed by a Markdown file.

Viewport width
Desktop100%whatever the page has
tanstacktanstack add https://adamjurek.com/r/tanstack/folder-shelf.jsonshadcnpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/folder-shelf.json

What it is made of

FolderShelf is the desktop and the window manager: the icons, and which windows exist.

DeskWindow is one window - dragging, resizing, closing, stacking.

useDeskStateuseDeskStateWhich windows are open, where they sit and what has been put away, remembered without breaking a server render.@sushindustries/ui · layout is where the arrangement lives, and the only part that touches storage.

ContextMenu is the menu on every icon, reachable three ways.

Four pieces rather than one, because three of them are useful on their own and the fourth is only interesting when it has somewhere to put things.

It stopped being a <dialog>

The first version opened folders with showModal(), which is genuinely the better answer for a modal on a page: focus trapping, Escape, inertness behind it and top-layer stacking, all free.

It is the wrong answer for a desktop. A modal dialog goes to the top layer by definition, so it covered the browser window rather than the screen it belongs to, and only one could ever be open. Windows are absolutely positioned panels now; Escape and focus are done by hand, and the stacking is a z each window carries - which is also what makes front-to-back survive a reload.

The portal went with it

Positioning them inside the desk removed the portal, and with it a whole class of bug: a hydration mismatch from a typeof document branch, and position: fixed measuring against a rotated laptop lid instead of the viewport. Both had already happened.

Install

tanstack add https://adamjurek.com/r/tanstack/folder-shelf.json
shell
pnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/folder-shelf.json
shell
pnpm add @sushindustries/ui @sushindustries/atoms
shell

What you get

Version0.1.0
Categorylayout · Containers
Filesfolder-shelf.tsx, context-menu.tsx, desk-window.tsx, use-desk-state.ts, icon.tsx
DependenciesNone
Also installscontext-menuContext MenuOne menu, reachable by right-click, by long press, and by a button. Escape and arrow keys included.@sushindustries/ui · layout, desk-windowDesk WindowA window you can drag, close and stack. Position is written to the element during a drag and to state only on release.@sushindustries/ui · layout, use-desk-stateuseDeskStateWhich windows are open, where they sit and what has been put away, remembered without breaking a server render.@sushindustries/ui · layout
Tagsblock, dialog, tree, touch, no-deps

No runtime dependencies

It brings nothing with it beyond the stylesheet.

UsesContext MenuContext MenuOne menu, reachable by right-click, by long press, and by a button. Escape and arrow keys included.@sushindustries/ui · layoutDesk WindowDesk WindowA window you can drag, close and stack. Position is written to the element during a drag and to state only on release.@sushindustries/ui · layoutuseDeskStateuseDeskStateWhich windows are open, where they sit and what has been put away, remembered without breaking a server render.@sushindustries/ui · layout