Log Portfolio’s window management system is modelled after a minimal OS window manager, implemented entirely in React context and state.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/log-portfolio/llms.txt
Use this file to discover all available pages before exploring further.
WindowContext holds an array of live window descriptors and exposes a focused set of functions for opening, closing, and manipulating those windows. Any component that calls useWindows() can read and drive the entire windowing system — no prop-drilling required.
WindowData Shape
Every entry in thewindows array is a WindowData object assembled when a window is first opened. The shape is:
WindowContext initialises these fields automatically when you call openWindow() — you only need to provide id, title, icon, content, and defaultSize.
WindowContext API
The context object returned byuseWindows() exposes the following values and functions.
windows: WindowData[]
The live array of all currently open windows. Components like Taskbar map over this array to render one button per window.
openWindow(windowData)
Opens a new window or focuses an existing one. If a window with the same id is already in the array, openWindow calls focusWindow(id) instead of creating a duplicate — so double-clicking the same desktop icon twice will bring the window to the front rather than stacking two copies. When a new window is created the global z-index counter is incremented and the new window receives the fresh value.
closeWindow(id)
Removes the window with the given id from the windows array entirely. If the closed window was the active window, activeWindowId is cleared to null. The Framer Motion AnimatePresence wrapper in Window.js plays the exit animation (scale down + slide to y: 100vh) before the component unmounts.
minimizeWindow(id)
Sets isMinimized: true on the target window. The Window component checks this flag and returns null when it is true, so the window disappears from the desktop while remaining in the windows array (which keeps its taskbar button alive). If the minimized window was active, activeWindowId is cleared.
restoreWindow(id)
Un-minimizes a window by delegating directly to focusWindow(id), which sets isMinimized: false, assigns a new z-index, and marks the window as active. This is the function the Taskbar calls when a user clicks a minimized window’s button.
maximizeWindow(id)
Toggles isMaximized on the target window, then calls focusWindow(id) to bring it forward. When isMaximized is true, the Window component animates to width: 100vw and height: calc(100vh - 40px) (leaving room for the Taskbar) and disables dragging.
focusWindow(id)
The core focus primitive. It increments the global z-index counter, writes the new value to the target window’s zIndex field, and sets activeWindowId to that window’s id. Called directly on onMouseDown in the Window component so that clicking anywhere inside a window brings it to the front.
activeWindowId: string | null
The id of the currently focused window, or null if no window is active (e.g. after all windows are minimized or closed). The Window component reads this to conditionally apply the titlebar-active CSS class, giving focused windows the characteristic blue Win98 title bar.
useWindows() Hook
useWindows() is the public interface for reading and driving the window system. It reads from WindowContext and throws a descriptive error if called outside a WindowProvider, making misconfigured usage immediately obvious in development.
useWindows() must be called inside a component that is a descendant of WindowProvider. If you call it outside this boundary, it throws: "useWindows must be used within a WindowProvider".Window Component Internals
TheWindow component in components/Window.js is responsible for rendering a single window frame and wiring all interactive behaviour to WindowContext.
Dragging
Dragging is implemented with Framer Motion’sdrag prop on the root motion.div. The drag handle is scoped to the title bar via dragHandle=".title-bar", so only dragging the title bar moves the window. Drag is automatically disabled when isMaximized is true — passing drag={!windowData.isMaximized} is all that’s needed.
When a drag ends, the onDragEnd callback receives the final offset and adds it to the window’s current x/y position, stored in local component state:
Resizing
The resize handle is a smalldiv anchored to the bottom-right corner of every non-maximized window. It uses raw mousedown, mousemove, and mouseup listeners attached to document to track the drag delta and update the window’s size state:
200px wide and 150px tall.
Animations
AnimatePresence from Framer Motion wraps the window list so that enter and exit transitions play correctly. Each window animates in with:
React Portal
EachWindow renders via ReactDOM.createPortal() targeting the document root. This means the window div is inserted as a direct child of <body> rather than being nested inside the Desktop component tree, which prevents any parent overflow: hidden or z-index stacking context from clipping windows.
Registering and Opening a New Window
The following example shows how to add a new “README” app to the desktop registry and open it programmatically from an arbitrary component. Step 1 — Add an entry to the app registry inDesktop.js: