Desk Window

@sushindustries/ui

A window you can drag, resize, close and stack, without re-rendering its contents every frame.

6 min read
View as MarkdownEdit on GitHub

Examples are the tab where the component is shown doing a job, not demonstrating a prop. The API tab already lists the props.

Viewport width
Phone22remthe floor, the narrowest this promises to work at
tanstacktanstack add https://adamjurek.com/r/tanstack/desk-window.jsonshadcnpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/desk-window.json

Press Compare. The frames are real viewports, so a layout that breaks at 320 breaks here too rather than in somebody's hands.

In a page

import { useState } from "react";
import { DeskWindow } from "@sushindustries/ui";

interface OpenWindow {
	id: string;
	title: string;
	x: number;
	y: number;
	z: number;
}

export function Desk({ windows, onChange }: {
	windows: OpenWindow[];
	onChange: (next: OpenWindow[]) => void;
}) {
	const [top, setTop] = useState(windows.length);

	return (
		<div className="relative" style={{ height: 480 }}>
			{windows.map((win) => (
				<DeskWindow
					key={win.id}
					title={win.title}
					x={win.x}
					y={win.y}
					z={win.z}
					onMove={(x, y) =>
						onChange(windows.map((w) => (w.id === win.id ? { ...w, x, y } : w)))
					}
					onRaise={() => {
						const z = top + 1;
						setTop(z);
						onChange(windows.map((w) => (w.id === win.id ? { ...w, z } : w)));
					}}
					onClose={() => onChange(windows.filter((w) => w.id !== win.id))}
				>
					<p className="p-4 fg-dim m-0 text-sm">{win.title}'s contents</p>
				</DeskWindow>
			))}
		</div>
	);
}
tsx

What this example is not

Not the whole desk. Deciding which windows exist, and assigning the next z on raise, is left to the host - here folded into one component for brevity, but on the real site that bookkeeping lives in its own hook (useDeskStateuseDeskStateWhich windows are open, where they sit and what has been put away, remembered without breaking a server render.@sushindustries/ui · layout) so it can also persist to storage.

UsesIconIconThe glyph set, generated from a Markdown table where every drawing carries its reason. One component, typed names, no icon font.@sushindustries/ui · content
Used byFolder ShelfFolder ShelfA desktop of folders that open into draggable windows, several at once, remembered between visits.@sushindustries/ui · layout