Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/old-windows/llms.txt

Use this file to discover all available pages before exploring further.

The Window component is the visual and interactive shell for every application in Old Windows. It wraps any arbitrary React content in an authentic Windows 98–style frame complete with a navy active-title-bar, Framer Motion drag, an animated open transition, and a WebRing navigation status bar at the bottom. Desktop creates one Window per entry in the windows state array.

The windowData Prop

Window accepts a single windowData prop — a plain object shaped by WindowContext and passed straight from the windows state array.
id
string
required
Unique identifier for the window. Used as the React key, and passed to every window management action (closeWindow, focusWindow, etc.).
title
string
required
Text displayed in the title bar and on the corresponding Taskbar button.
component
ReactNode
required
The content rendered inside the window body. Desktop constructs this as <app.component /> before calling openWindow.
icon
ReactNode
required
Emoji or node shown to the left of the title in both the title bar and the Taskbar button.
state
'open' | 'minimized' | 'maximized'
required
Current lifecycle state. The component returns null immediately when state === 'minimized', removing it from the DOM.
zIndex
number
required
CSS stacking order. Incremented globally by focusWindow each time a window is brought to front.
width
number
Initial width in pixels. Applied as an inline style on the motion container. Defaults to 600 if omitted via openWindow.
height
number
Initial height in pixels. Applied as an inline style on the motion container. Defaults to 400 if omitted via openWindow.
defaultX
number
Initial horizontal offset from the left edge of the desktop in pixels. Used as the Framer Motion x starting position.
defaultY
number
Initial vertical offset from the top edge of the desktop in pixels. Used as the Framer Motion y starting position.

Behavior

Minimized State

When state === 'minimized', Window returns null immediately. The window disappears from the desktop but remains in the windows array so its Taskbar button stays visible. Clicking the Taskbar button calls restoreWindow, which sets state back to 'open'.

Maximized State

When state === 'maximized', the window fills the full viewport width and calc(100% - 40px) height (leaving room for the Taskbar). The className adds w-full h-full top-0 left-0, and the inline style sets width: '100%' and height: 'calc(100% - 40px)'. Framer Motion drag is disabled via drag={!isMaximized}.

Title Bar Styles

ConditionTitle Bar Classes
This window is the active windowbg-win-navy text-white
Any other windowbg-win-gray-dark text-win-gray-light
Clicking anywhere on a window fires onMouseDown, which calls focusWindow(id) to bring it to front and apply the active title bar style.

Drag

Dragging is powered by Framer Motion’s drag and dragControls props. dragControls.start(event) is called from an onPointerDown handler attached to the title bar div, so only the title bar initiates a drag. The props are:
  • drag={!isMaximized} — drag is enabled only when the window is not maximized
  • dragControls — a useDragControls() instance
  • dragListener={false} — disables Framer Motion’s built-in pointer listener so only the manual dragControls.start() triggers drags
  • dragMomentum={false} — windows stop exactly where released, no sliding

Open Animation

On mount, each window animates from { x: defaultX, y: defaultY, scale: 0.9, opacity: 0 } to { scale: 1, opacity: 1 } using Framer Motion’s initial / animate props, giving it a snappy pop-in at its configured starting position. When the window is maximized, the initial prop is set to false to skip the entry animation, and it animates to { x: 0, y: 0, scale: 1, opacity: 1 }.

Double-click Title Bar

Double-clicking the title bar toggles between 'maximized' and 'open' states via maximizeWindow / restoreWindow.

Title Bar Buttons

1

Minimize

Renders a <span className="block w-2 h-0.5 bg-black mt-2"> — a small horizontal bar — inside a win-border-outset button. Calls minimizeWindow(id), setting state to 'minimized' and removing the window from the DOM.
2

Maximize / Restore

When unmaximized: renders <div className="w-2.5 h-2.5 border border-black border-t-2"> (a square with a thick top border). When maximized: renders a restore SVG (10×10) with two overlapping rectangles drawn via <path>. Calls maximizeWindow(id) or restoreWindow(id) accordingly.
3

Close

Renders an X SVG (8×8) with two crossing <line> elements. Calls closeWindow(id), which removes the window object from the windows array entirely.

WebRing Status Bar

A status bar sits at the bottom of every window body. It contains three equally styled win-border-outset buttons that navigate between apps using the global apps config array. Each button first closes the current window via closeWindow(id), then opens the target app:
ButtonBehavior
< PrevCloses current window, then opens apps[(index - 1 + length) % length]
RandomCloses current window, then opens a randomly selected app
Next >Closes current window, then opens apps[(index + 1) % length]
This mimics classic late-90s WebRing navigation, cycling through the portfolio sections.

Example

The following is how Desktop constructs a windowData object and passes it to Window:
<Window windowData={{
  id: 'about',
  title: 'about_me.html',
  component: <AboutComponent />,
  icon: '👤',
  state: 'open',
  zIndex: 11,
  width: 500,
  height: 450,
  defaultX: 80,
  defaultY: 80
}} />
You do not construct windowData objects manually in practice. Call openWindow() from useWindows() and the WindowProvider creates the object and adds it to the windows array automatically.

Build docs developers (and LLMs) love