Overview
The Windows component manages all open application windows with full drag, resize, and window control capabilities. It implements authentic Windows XP window styling and behavior.
Component Structure
function Windows ({
apps , // Array of open applications
onMouseDown , // Focus handler
onClose , // Close handler
onMinimize , // Minimize handler
onMaximize , // Maximize handler
focusedAppId , // Currently focused app ID
}) {
return (
< div style = { { position: 'relative' , zIndex: 0 } } >
{ apps . map ( app => (
< StyledWindow
show = { ! app . minimized }
key = { app . id }
id = { app . id }
onMouseDown = { onMouseDown }
onMouseUpClose = { onClose }
onMouseUpMinimize = { onMinimize }
onMouseUpMaximize = { onMaximize }
isFocus = { focusedAppId === app . id }
{ ... app }
/>
)) }
</ div >
);
}
Source: src/WinXP/Windows/index.jsx:8-33
Window Props
Each window receives the following props:
Prop Type Description idnumberUnique window identifier headerobjectHeader configuration (icon, title, buttons) defaultSizeobjectInitial size: { width, height } defaultOffsetobjectInitial position: { x, y } resizablebooleanWhether window can be resized maximizedbooleanCurrent maximize state minimizedbooleanCurrent minimize state minWidthnumberMinimum window width minHeightnumberMinimum window height zIndexnumberStacking order isFocusbooleanWhether window has focus componentfunctionApplication component to render injectPropsobjectProps to pass to app component
Source: src/WinXP/Windows/index.jsx:35-53
The window header displays the application icon, title, and control buttons.
Structure
< header
className = "app__header"
ref = { dragRef }
onDoubleClick = { onDoubleClickHeader }
>
< img
onDoubleClick = { _onMouseUpClose }
src = { header . icon }
alt = { header . title }
className = "app__header__icon"
draggable = { false }
/>
< div className = "app__header__title" > { header . title } </ div >
< HeaderButtons
buttons = { header . buttons }
onMaximize = { _onMouseUpMaximize }
onMinimize = { _onMouseUpMinimize }
onClose = { _onMouseUpClose }
maximized = { maximized }
resizable = { resizable }
isFocus = { isFocus }
/>
</ header >
Source: src/WinXP/Windows/index.jsx:119-142
Focused and unfocused windows have different gradient backgrounds:
. header__bg {
background : $ {({ isFocus }) =>
isFocus
? 'linear-gradient(to bottom,#0058ee 0%,#3593ff 4%,...,#003092 100%)'
: 'linear-gradient(to bottom, #7697e7 0%,...,#abbae3 100%)' };
position : absolute ;
left : 0 ;
top : 0 ;
right : 0 ;
height : 28 px ;
border - top - left - radius : 8 px ;
border - top - right - radius : 8 px ;
}
Source: src/WinXP/Windows/index.jsx:163-177
Double-clicking the header icon closes the window, matching Windows XP behavior.
Window control buttons (minimize, maximize, close) are rendered separately.
Component
function HeaderButtons ({
buttons , // Array of button types
onMaximize ,
onMinimize ,
onClose ,
maximized ,
resizable ,
className ,
}) {
const buttonElements = {
minimize : (
< button
key = "minimize"
className = "header__button header__button--minimize"
onMouseUp = { onMinimize }
/>
),
maximize : (
< button
key = "maximize"
className = { `header__button ${
maximized ? 'header__button--maximized' : 'header__button--maximize'
} ${ resizable ? '' : 'header__button--disable' } ` }
onMouseUp = { onMaximize }
/>
),
close : (
< button
key = "close"
className = "header__button header__button--close"
onMouseUp = { onClose }
/>
),
};
return (
< div className = { className } >
{ buttons ? (
buttons . map ( b => buttonElements [ b ])
) : (
<>
{ buttonElements . minimize }
{ buttonElements . maximize }
{ buttonElements . close }
</>
) }
</ div >
);
}
Source: src/WinXP/Windows/HeaderButtons.jsx:4-52
.header__button {
margin-right : 1 px ;
position : relative ;
width : 22 px ;
height : 22 px ;
border : 1 px solid #fff ;
border-radius : 3 px ;
}
.header__button--close {
box-shadow : inset 0 -1 px 2 px 1 px #da4600 ;
background-image : radial-gradient (
circle at 90 % 90 % ,
#cc4600 0 % ,
#dc6527 55 % ,
#cd7546 70 % ,
#ffccb2 90 % ,
white 100 %
);
}
Source: src/WinXP/Windows/HeaderButtons.jsx:61-157
Drag and Resize
Windows use the useElementResize hook for drag and resize functionality.
Hook Usage
const { offset , size } = useElementResize ( ref , {
dragRef , // Element that initiates drag
defaultOffset , // Starting position
defaultSize , // Starting size
boundary: { // Screen boundaries
top: 1 ,
right: windowWidth - 1 ,
bottom: windowHeight - 31 , // Leave room for taskbar
left: 1 ,
},
resizable , // Enable resize handles
resizeThreshold: 10 , // Resize handle thickness
minWidth , // Minimum width constraint
minHeight , // Minimum height constraint
});
Source: src/WinXP/Windows/index.jsx:74-88
Position Calculation
let width , height , x , y ;
if ( maximized ) {
width = windowWidth + 6 ;
height = windowHeight - 24 ; // Leave room for taskbar
x = - 3 ;
y = - 3 ;
} else {
width = size . width ;
height = size . height ;
// Safety clamp: Ensure visual size never drops below minimum
if ( minWidth && width < minWidth ) width = minWidth ;
if ( minHeight && height < minHeight ) height = minHeight ;
x = offset . x ;
y = offset . y ;
}
Source: src/WinXP/Windows/index.jsx:90-106
Maximized windows extend slightly beyond viewport bounds (-3px) to hide the window border.
Window Actions
Opening Windows
Windows are opened by dispatching the ADD_APP action:
dispatch ({
type: ADD_APP ,
payload: appSettings [ 'Internet Explorer' ]
});
The reducer handles single vs. multi-instance apps:
case ADD_APP : {
const existingApp = state . apps . find (
_app =>
_app . component === action . payload . component && ! _app . multiInstance ,
);
if ( action . payload . multiInstance || ! existingApp ) {
// Create new window
return {
... state ,
apps: [
... state . apps ,
{
... action . payload ,
id: state . nextAppID ,
zIndex: state . nextZIndex ,
minimized: false ,
},
],
nextAppID: state . nextAppID + 1 ,
nextZIndex: state . nextZIndex + 1 ,
focusing: FOCUSING . WINDOW ,
};
}
// Focus existing window
const appsWithFocus = state . apps . map ( app =>
app . component === action . payload . component
? { ... app , zIndex: state . nextZIndex , minimized: false }
: app ,
);
return {
... state ,
apps: appsWithFocus ,
nextZIndex: state . nextZIndex + 1 ,
focusing: FOCUSING . WINDOW ,
};
}
Source: src/WinXP/reducer.js:30-63
Closing Windows
case DEL_APP : {
const remainingApps = state . apps . filter ( app => app . id !== action . payload );
let nextFocusing = FOCUSING . DESKTOP ;
if ( remainingApps . length > 0 ) {
nextFocusing = FOCUSING . WINDOW ;
} else if ( state . icons . find ( icon => icon . isFocus )) {
nextFocusing = FOCUSING . ICON ;
}
return {
... state ,
apps: remainingApps ,
focusing: nextFocusing ,
};
}
Source: src/WinXP/reducer.js:64-77
Minimizing Windows
case MINIMIZE_APP : {
const apps = state . apps . map ( app =>
app . id === action . payload ? { ... app , minimized: true } : app ,
);
const openWindows = apps . filter ( app => ! app . minimized );
let nextFocusing = FOCUSING . DESKTOP ;
if ( openWindows . length > 0 ) {
nextFocusing = FOCUSING . WINDOW ;
} else if ( state . icons . find ( icon => icon . isFocus )) {
nextFocusing = FOCUSING . ICON ;
}
return {
... state ,
apps ,
focusing: nextFocusing ,
};
}
Source: src/WinXP/reducer.js:91-107
Maximizing Windows
case TOGGLE_MAXIMIZE_APP : {
const apps = state . apps . map ( app =>
app . id === action . payload ? { ... app , maximized: ! app . maximized } : app ,
);
return {
... state ,
apps ,
focusing: FOCUSING . WINDOW ,
};
}
Source: src/WinXP/reducer.js:108-117
Double-clicking the header toggles maximize state if the window is resizable.
Z-Index and Focus
Getting Focused Window
const getFocusedAppId = useCallback (() => {
if ( state . focusing !== FOCUSING . WINDOW ) return - 1 ;
const focusedApp = [ ... state . apps ]
. filter ( app => ! app . minimized ) // Ignore minimized windows
. sort (( a , b ) => b . zIndex - a . zIndex )[ 0 ]; // Highest z-index
return focusedApp ? focusedApp . id : - 1 ;
}, [ state . apps , state . focusing ]);
Source: src/WinXP/index.jsx:68-74
Focus Behavior
When a window is clicked:
function _onMouseDown () {
onMouseDown ( id ); // Triggers FOCUS_APP action
}
This updates the z-index:
case FOCUS_APP : {
const apps = state . apps . map ( app =>
app . id === action . payload
? { ... app , zIndex: state . nextZIndex , minimized: false }
: app ,
);
return {
... state ,
apps ,
nextZIndex: state . nextZIndex + 1 , // Increment for next focus
focusing: FOCUSING . WINDOW ,
};
}
Source: src/WinXP/reducer.js:78-89
Window Content
The application component is rendered inside the window:
< div className = "app__content" >
{ component ({
onClose: _onMouseUpClose ,
onMinimize: _onMouseUpMinimize ,
isFocus ,
... injectProps , // Custom props passed to app
}) }
</ div >
Source: src/WinXP/Windows/index.jsx:143-151
Injected Props
All window applications receive:
onClose - Function to close the window
onMinimize - Function to minimize the window
isFocus - Boolean indicating focus state
Additional props from injectProps
Window Visibility
Minimized windows are hidden but remain in state:
const StyledWindow = styled ( Window ) `
display: ${ ({ show }) => ( show ? 'flex' : 'none' ) } ;
position: absolute;
// ...
` ;
< StyledWindow
show = { ! app . minimized } // Hide when minimized
// ...
/>
Source: src/WinXP/Windows/index.jsx:155-156
Next Steps
Desktop Overview Return to desktop architecture
Icons Learn about desktop icons
Taskbar Explore taskbar window buttons