npm package: @gregadamski/desktop-system
Description: A React-based desktop environment simulation component library. Create a desktop-like interface with windows, taskbar, and widgets within your web application.
Latest version: 0.0.5

# 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

```bash
npm install @gregadamski/desktop-system
```

## Usage

Here is a basic example of how to use the `Desktop` component in your application.

```tsx
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.

```tsx
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:**

```tsx
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:**

```tsx
import { FlexContainer } from '@gregadamski/desktop-system';

export const MyWidget = () => (
  <FlexContainer direction="column" gap={2} padding={3}>
    <Header />
    <MainContent />
    <Footer />
  </FlexContainer>
);
```

### Best Practices

1. **Always use a container component** - Wrap your widget content in either `AppContainer` or `FlexContainer` to ensure proper scrolling behavior.

2. **Choose the right container**:
   - Use `AppContainer` for simple content without specific layout requirements
   - Use `FlexContainer` when you need flexbox layout features (direction, gap, alignment, etc.)

3. **Avoid hardcoded heights** - Let the containers handle sizing and overflow automatically.

4. **Customize scrollbars** - Both containers include styled scrollbars that work across browsers, but you can override them using the `sx` prop.

```tsx
<AppContainer 
  sx={{
    '&::-webkit-scrollbar-thumb': {
      backgroundColor: 'primary.main',
    }
  }}
>
  {/* content */}
</AppContainer>
```