$ show nomcopter/react-mosaic
This repository is a React component library, react-mosaic-component, that implements a tiling window manager (nested resizable/draggable panels) as a controlled or uncontrolled React component. It allows users to arrange panels in an n-ary tree of splits, tabs, and leaf nodes, with full drag-and-drop reordering, resizing, tab management, and theming support. The codebase is a well-structured Nx monorepo with a Docusaurus documentation site, a live demo, CI/CD pipelines, and extensive unit tests. While functionally complete and battle-tested, the code reveals some technical debt: a mix of class components and hooks, occasional `any` type usage, a reliance on `immutability-helper` for all tree mutations, and an active legacy binary-tree migration path that adds maintenance surface. The architecture is sound for its domain, and the immutable tree update factories and drag-and-drop state machine demonstrate non-trivial engineering.
The LLM identified 4 files worth highlighting for reuse:
Provides `updateTree()` and factory functions (`createRemoveUpdate`, `createHideUpdate`, `createExpandUpdate`, `createDragToUpdates`, `createSwapUpdates`, `createAddChildUpdate`) that apply typed `MosaicUpdate` specs using `immutability-helper`. Each factory returns a composable, testable update specification, enabling sequential application for complex drag-drop operations (remove then re-add). This pattern is reusable for any nested immutable state tree that needs declarative mutations.
A component that renders a draggable divider between two panes. Implements complex resize logic: minimum pane sizes (percentage and pixel, per-direction, bounding-box-aware), throttled pointer-move (30fps via lodash.throttle), a preview mode that only moves the divider visually until mouseup, and a `pointer-events: none` class on `<html>` during drag to block iframes and sub-window capture. The grab offset, z-index stacking for overlapping handles, and recovery on window blur demonstrate solid craftsmanship.
A draggable tab component using `react-dnd`'s `useDrag` hook. Handles tab reorder within the same group, swap with another leaf, and drag to external targets. Integrates with touch gesture detection (`touchGesture.ts`) to differentiate between tap and long-press drag, with a configurable 10px touch slop to avoid swallowing clicks. Demonstrates a well-encapsulated drag source that respects the full drag lifecycle (hide/show, swap, drop meta) while remaining tightly coupled to the mosaic tree context.
Implements a gesture tracker (`trackTouchGestures`) that monitors `touchstart`/`touchmove`/`touchend` events to detect long-press activation (configurable delay and distance threshold) and distinguish between a tap and a drag. Returns callbacks for `onLongPress` and `onSwipe`. This is a self-contained pattern that can be extracted into any web app needing touch-based drag initiation without conflicting with native scrolling or tapping.