react-grid-layout
The Holoprojector layout editor — drag-resizable tile arrangements persisted server-side.
react-grid-layout (^2.2.3, with @types/react-grid-layout) powers the
Holoprojector's tile editor and the runtime panel view. Layouts are persisted in
TrailBase as cols × rows + a list of tile rectangles (no feed bindings — those live
on Panels).
Where it lives in src/
| File | Role |
|---|---|
src/app/restreaming/holoprojector/page.tsx | The editor route — mounts the grid in edit mode |
src/components/restreaming/LayoutEditor.tsx | The grid component itself — handles drag, resize, save |
src/components/restreaming/PanelViewer.tsx | The runtime view — same layout shape, but read-only and rendering player tiles |
src/components/restreaming/HoloVidsProjectionCard.tsx | The smaller card that previews a layout in lists |
src/lib/holovidsLayouts.ts | TrailBase CRUD for layout records |
Layout shape
A layout is { cols: number, rows: number, items: { i: string, x: number, y: number, w: number, h: number }[] }.
Tile rectangles are validated server-side: no overlaps, no out-of-bounds, no negative
sizes.
Edit-mode invariants
- Snap to integer grid. Sub-cell positions aren't allowed; the grid is the contract.
- Min tile size 1×1. Sub-1 tiles are a UX trap (no room for the player chrome).
- Bounded. Tiles can't drag outside
cols × rows. - No overlap. react-grid-layout's
preventCollision: trueplus a save-time validator.
View-mode rendering
In the runtime PanelViewer, the same layout shape drives a CSS grid (not react-grid-
layout — the runtime doesn't need drag, and CSS grid renders faster). The shared
contract is the { i, x, y, w, h } shape; both the editor and the viewer parse the
same TrailBase row.
What it does not do
- No multi-breakpoint responsive layouts. Holoprojector targets large displays (kiosks, ops rooms); we don't reflow on mobile.
- No nested grids. A layout is one grid; if you need a sub-layout, it's a new panel.
- No animation. Drag is instant; no spring physics, no inertia.
See also
- Holoprojector
- TrailBase — where layouts persist