@gregadamski/desktop-system
v0.0.5
Published
A React-based desktop environment simulation component library. Create a desktop-like interface with windows, taskbar, and widgets within your web application.
Readme
Desktop System
A React-based desktop environment simulation component library. Create a desktop-like interface with windows, taskbar, and widgets within your web application.
Installation
npm install @gregadamski/desktop-systemUsage
Here is a basic example of how to use the Desktop component in your application.
import React, { useRef } from 'react';
import { Desktop, defaultWidgetRegistry, DesktopHandle } from '@gregadamski/desktop-system';
const App = () => {
const desktopRef = useRef<DesktopHandle>(null);
return (
<div style={{ width: '100vw', height: '100vh' }}>
<Desktop
ref={desktopRef}
registry={defaultWidgetRegistry}
/>
</div>
);
};
export default App;Components
<Desktop />
The main container component that renders the desktop environment, including the background, windows, and taskbar.
Props:
| Prop | Type | Description |
|------|------|-------------|
| registry | Record<string, ComponentDefinition> | A registry of available widgets/apps. |
| theme | Theme (optional) | Custom MUI theme. If not provided, uses the default theme. |
| ref | Ref<DesktopHandle> | Ref to access desktop methods like getState and loadConfig. |
DesktopHandle
The ref passed to <Desktop /> exposes the following methods:
getState(): Returns the current state of the desktop (open windows, positions, etc.).loadConfig(state: DesktopState): Restores the desktop to a specific state.
Configuration
Widget Registry
The registry defines the applications available on the desktop. You can use the defaultWidgetRegistry or create your own.
import { ComponentDefinition } from '@gregadamski/desktop-system';
const myRegistry: Record<string, ComponentDefinition> = {
myApp: {
id: 'myApp',
name: 'My Application',
icon: <MyIcon />,
component: MyAppWidget,
defaultSize: { w: 400, h: 300 },
defaultConfig: {}
}
};Building Custom Widgets
When creating custom widgets/applications for the desktop, you should use the provided container components to ensure proper scrolling behavior when content overflows the window boundaries.
Container Components
<AppContainer />
A simple wrapper component that provides automatic scrolling with styled scrollbars.
Props:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | ReactNode | - | The content to render |
| padding | number \| string | 2 | Padding inside the container |
| horizontalScroll | boolean | false | Enable horizontal scrolling |
| verticalScroll | boolean | true | Enable vertical scrolling |
| sx | SxProps<Theme> | {} | Additional MUI sx props |
Example:
import { AppContainer } from '@gregadamski/desktop-system';
export const MyWidget = () => (
<AppContainer padding={3}>
<Typography variant="h5">My Application</Typography>
<Typography>
Content here will automatically scroll if it overflows
the window boundaries.
</Typography>
</AppContainer>
);<FlexContainer />
A flexbox-based wrapper component that provides structured layouts with automatic scrolling.
Props:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | ReactNode | - | The content to render |
| direction | 'row' \| 'column' \| 'row-reverse' \| 'column-reverse' | 'column' | Flex direction |
| gap | number \| string | 2 | Gap between items |
| align | 'flex-start' \| 'center' \| 'flex-end' \| 'stretch' \| 'baseline' | 'stretch' | Align items |
| justify | 'flex-start' \| 'center' \| 'flex-end' \| 'space-between' \| 'space-around' \| 'space-evenly' | 'flex-start' | Justify content |
| padding | number \| string | 2 | Padding inside the container |
| wrap | 'nowrap' \| 'wrap' \| 'wrap-reverse' | 'nowrap' | Flex wrap |
| horizontalScroll | boolean | false | Enable horizontal scrolling |
| verticalScroll | boolean | true | Enable vertical scrolling |
| sx | SxProps<Theme> | {} | Additional MUI sx props |
Example:
import { FlexContainer } from '@gregadamski/desktop-system';
export const MyWidget = () => (
<FlexContainer direction="column" gap={2} padding={3}>
<Header />
<MainContent />
<Footer />
</FlexContainer>
);Best Practices
Always use a container component - Wrap your widget content in either
AppContainerorFlexContainerto ensure proper scrolling behavior.Choose the right container:
- Use
AppContainerfor simple content without specific layout requirements - Use
FlexContainerwhen you need flexbox layout features (direction, gap, alignment, etc.)
- Use
Avoid hardcoded heights - Let the containers handle sizing and overflow automatically.
Customize scrollbars - Both containers include styled scrollbars that work across browsers, but you can override them using the
sxprop.
<AppContainer
sx={{
'&::-webkit-scrollbar-thumb': {
backgroundColor: 'primary.main',
}
}}
>
{/* content */}
</AppContainer>