# free-range-divs

> Have you ever wanted to build a web page that behaves like a desktop? Think ``s that behave like windows, with dragging and resizing that works the way you expect.

Latest version **2.0.2** (published 2025-12-07) · MIT license · 0 weekly downloads

## Install

```sh
npm install free-range-divs
pnpm add free-range-divs
yarn add free-range-divs
bun add free-range-divs
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; has provenance.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.0.2 |
| Published | 2025-12-07 |
| First published | 2020-07-31 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 17.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| Author | David Mann |
| Maintainers | davemn |

## Links

- npm: https://www.npmjs.com/package/free-range-divs
- Repository: https://github.com/davemn/free-range-divs
- Homepage: https://github.com/davemn/free-range-divs#readme
- Issues: https://github.com/davemn/free-range-divs/issues
- npm.io page: https://npm.io/package/free-range-divs

## Recent versions

- 2.0.2 (latest) — 2025-12-07
- 1.0.0 — 2025-02-26
- 0.1.1 — 2020-07-31

## README

# Free Range `<Div>`s

Have you ever wanted to build a web page that behaves like a desktop?
Think `<div>`s that behave like windows, with dragging and resizing that works the way you expect.

Or maybe you're building a workspace-style app, but need something less rigid than a Kanban board or tiling dashboard.

Or maybe you're making an avant-garde design for your personal website?

`free-range-divs` is for you.

![An illustration of two layered windows. The nearest window is title "App Window". The background window is titled "Background Window".](/assets/promo.png?raw=true)

# What's in the box?

Currently it's two React components:

- `<Desktop>` - Coordinates the child `<FreeDiv>`s. It's the sandbox for absolute positioning of the `<FreeDiv>`s.
- `<FreeDiv>` - A minimally-styled container that holds your component. **You decide** how your content should look. `<FreeDiv>` takes care of movement and resizing.

# How do I install it?

```bash
> yarn add free-range-divs
```

# Can I see it in action?

Yep, [have fun!](https://musing-varahamihira-b4d852.netlify.app/)

# API

By example:

```js
<Desktop width={1024} height={768}>
  <FreeDiv key="app-notepad">
    {({ isActive, titleProps }) => (
      <div className={`my-window ${isActive ? 'my-window--active' : ''}`}>
        <div className="my-window__title" {...titleProps}>
          notepad.exe - Hello World
        </div>
        <h1>Window contents.</h1>
      </div>
    )}
  </FreeDiv>
  <FreeDiv key="app-chrome">
    {({ isActive, titleProps }) => (
      <div className={`my-window ${isActive ? 'my-window--active' : ''}`}>
        <div className="my-window__title" {...titleProps}>
          chrome.exe - Messageboard
        </div>
        <p>Leave a message...</p>
      </div>
    )}
  </FreeDiv>
</Desktop>
```

```css
.my-window {
  background-color: white;
  color: #888;
  border: 2px solid #ddd;
  height: calc(100% - 4px);
}
.my-window--active {
  color: black;
}
.my-window__title {
  background-color: #ddd;
  padding: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
```

Each `<FreeDiv>` takes a render function, that receives:

- `isActive`: Is this window the one currently on top?
- `titleProps`: Spread this on whichever element represents the area that initiates a window drag. Traditionally this is the title bar, but you can pass it to _any_ part of your component.

The render function should return _your component_. In the example above I show returning bare DOM elements with a couple of custom classNames. But those are just for demo!

## API - `<FreeDiv>` Only

Using the `<Desktop>` component is entirely optional! It provides tracking for which window among its children is "active". An active FreeDiv has a higher z-index than its siblings, and the `isActive` render prop is set to true.

If your app doesn't need to manage multiple `<FreeDiv>`s or if you're only interested in the drag/drop/resize functionality, `<FreeDiv>` can be used on its own. Note that the `isActive` prop passed to the render function never changes if there's no container `<Desktop>`!

## Deployment

For my own notes, but also for any future contributors.

Steps:

1. Merge all new features via PR.
2. (Admin only) `pnpm version [major|minor|patch]` on main branch.
3. (Admin only) `git push origin main`
4. (Admin only) `git push origin tag [vN.N]`

This will run the associated Github workflow to publish to NPM with trusted publishing.

---
_Source: https://npm.io/package/free-range-divs · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
