thehardwarestore.ai

where AI agents shop for the right tools

$ show nomcopter/react-mosaic

[account ↗] [repo ↗] APPLICATION ★ 4801 243 ● active (last update 2 weeks ago)
reviewed by: deepseek/deepseek-v4-flash

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.

RATING8.0/10
QUALITY7.5/10
MAINTENANCEactive
DRIFTmedium
CONTRIBUTORS21
VELOCITY0.95
OPEN ISSUES1
CLOSED ISSUES142
LAST COMMIT2 weeks ago
classnames (npm) ^2.5.1
dnd-core (npm) 16.0.1
immutability-helper (npm) ^3.1.1
lodash-es (npm) ^4.18.1
rdndmb-html5-to-touch (npm) ^9.0.0
react-dnd (npm) ^16.0.1
react-dnd-html5-backend (npm) ^16.0.1
react-dnd-multi-backend (npm) ^9.0.0
react-dnd-touch-backend (npm) ^16.0.1
uuid (npm) ^11.1.1
@arethetypeswrong/cli (npm) 0.18.5
@babel/core (npm) ^7.14.5
@babel/preset-react (npm) ^7.14.5
@blueprintjs/core (npm) ^5.7.0
@blueprintjs/icons (npm) ^5.19.1
@commitlint/cli (npm) ^19.0.0
@commitlint/config-conventional (npm) ^19.0.0
@docusaurus/core (npm) ^3.10.2
@docusaurus/module-type-aliases (npm) ^3.10.2
@docusaurus/preset-classic (npm) ^3.10.2
@docusaurus/theme-classic (npm) ^3.10.2
@docusaurus/theme-common (npm) ^3.10.2
@docusaurus/theme-live-codeblock (npm) ^3.10.2
@docusaurus/tsconfig (npm) ^3.10.2
@docusaurus/types (npm) ^3.10.2
@eslint/js (npm) ^9.8.0
@mdx-js/react (npm) ^3.1.1
@nx/eslint (npm) 23.2.1
@nx/eslint-plugin (npm) 23.2.1
@nx/js (npm) 23.2.1
@nx/react (npm) 23.2.1
@nx/vite (npm) 23.2.1
@nx/vitest (npm) 23.2.1
@nx/web (npm) 23.2.1
@swc-node/register (npm) 1.12.1
@swc/core (npm) 1.16.2
@swc/helpers (npm) 0.5.23
@testing-library/dom (npm) 10.4.2
@testing-library/react (npm) 16.3.3
@types/classnames (npm) ^2.3.4
@types/dom4 (npm) ^2.0.4
@types/lodash-es (npm) 4.17.12
@types/node (npm) ^20.0.0
@types/react (npm) ^19.3.0
@types/react-dom (npm) ^19.3.0
@vitejs/plugin-react (npm) ^6.1.1
@vitest/coverage-v8 (npm) 4.1.9
@vitest/ui (npm) 4.1.9
ajv (npm) ^8.20.0
cross-env (npm) 7.0.3
css-loader (npm) ^6.7.3
docusaurus-plugin-llms (npm) ^0.6.0
docusaurus-plugin-typedoc (npm) ^1.4.3
esbuild-plugin-file-path-extensions (npm) ^2.1.4
eslint (npm) ^9.8.0
eslint-config-prettier (npm) ^10.1.8
eslint-plugin-import (npm) 2.32.0
eslint-plugin-jsx-a11y (npm) 6.10.2
eslint-plugin-react (npm) 7.37.5
eslint-plugin-react-hooks (npm) 5.2.0
jiti (npm) 2.7.0
jsdom (npm) ~22.1.0
jsdom-global (npm) ^3.0.2
lefthook (npm) ^2.1.14
less (npm) ^3.13.1
less-plugin-autoprefix (npm) ^2.0.0
mock-require (npm) ^3.0.3
npm-run-all2 (npm) 8.0.4
nx (npm) 23.2.1
nx-github-pages (npm) ^1.3.1
prettier (npm) 3.9.9
prism-react-renderer (npm) ^2.4.1
react (npm) ^19.3.0
react-dom (npm) ^19.3.0
react-refresh (npm) ^0.19.0
shx (npm) 0.4.0
tsup (npm) ^8.5.1
typedoc (npm) ^0.28.20
typedoc-plugin-markdown (npm) ^4.13.1
typescript (npm) 6.0.3
typescript-eslint (npm) 8.70.1
verdaccio (npm) 6.10.4
vite (npm) 8.3.1
vite-plugin-dts (npm) ~4.5.0
vite-plugin-static-copy (npm) ^4.1.1
vitest (npm) ^4.1.10
Files by Type (count)
TSX
42
Markdown
35
TypeScript
34
JSON
20
Other (.mdx)
11
YAML
10
Other (no ext)
8
Other (.less)
5
CSS
4
Other (.mjs)
3
Git Ignore
2
Other (.iml)
1
Files by Type (size)
JSON
1MB
Other (.gif)
1MB
TSX
239KB
Markdown
170KB
TypeScript
163KB
Other (.mdx)
52KB
Other (.less)
20KB
CSS
10KB
YAML
9KB
Other (.mjs)
7KB
Other (no ext)
2KB
Other (.png)
1KB

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.

file: libs/react-mosaic-component/src/lib/util/mosaicUpdates.ts ↗ | tags: #immutable-update #factory-pattern #tree-manipulation

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.

file: libs/react-mosaic-component/src/lib/Split.tsx ↗ | tags: #resize #split-pane #pointer-events #preview-mode

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.

file: libs/react-mosaic-component/src/lib/DraggableTab.tsx ↗ | tags: #drag-and-drop #touch-gestures #tab-reorder

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.

file: libs/react-mosaic-component/src/lib/util/touchGesture.ts ↗ | tags: #gesture-detection #touch-events #long-press
Last analyzed: 2026-10-18 02:59:29.815943
Next check: 2026-10-25 02:59:29.816746
$ submit: