Drag-reorderable tile grid with per-tile width control + view-scoped
persistence. Native HTML5 drag — zero runtime deps (no @dnd-kit).
──────────────────────────────────────────────────────────────────
Module surface
──────────────────────────────────────────────────────────────────
<Workspace tiles storageKey persistence? columns? readOnly?>
Wave 13.F.1 + .2
- Native HTML5 drag-and-drop (draggable + dragover + drop)
- role=grid + per-cell role=gridcell + tabIndex=0
- Keyboard shortcuts on focused tile:
← / → resize span down/up (clamped 1..columns)
↑ / ↓ move tile up/down by one slot
- Per-tile 1/2/3/4 size buttons (suppressed in readOnly)
- Drop target gets dashed accent outline
- Reset-layout CTA (suppressed in readOnly)
useWorkspaceLayout(tiles, { storageKey, persistence })
- move(from, to) / resize(id, span) / reset()
- hydrated flag — true once initial load resolves
- One-shot load on mount, save on every change (post-hydration)
reconcile(layout, tiles) · exported pure fn
- Drops entries referencing removed tiles
- Appends new tiles in registry order with defaultSpan fallback
- Used by the hook on every tile-registry change
(defensive against schema drift between releases)
localStoragePersistence · default; SSR-safe (returns null when
window is absent)
──────────────────────────────────────────────────────────────────
Quality gates
──────────────────────────────────────────────────────────────────
✓ 10/10 tests passing
- reconcile: 3 cases (drop unknown / append new / preserve order)
- hook: 4 cases (hydrate defaults / move / resize / reset)
- component: 3 cases (renders cells / keyboard resize / readOnly)
✓ tsc build clean
──────────────────────────────────────────────────────────────────
Roadmap (lands in subsequent commit)
──────────────────────────────────────────────────────────────────
13.F.1 Drag-resize tiles
13.F.2 Saved views per route + persistence layer
Showcase /futurism/workspace (MAG.6) lands in the paired showcase
commit.
12 lines
247 B
JSON
12 lines
247 B
JSON
{
|
|
"extends": "../../tsconfig.base.json",
|
|
"compilerOptions": {
|
|
"outDir": "dist",
|
|
"rootDir": "src",
|
|
"lib": ["ES2022", "DOM"],
|
|
"jsx": "react-jsx"
|
|
},
|
|
"include": ["src"],
|
|
"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]
|
|
}
|