Editor: the toolkit is a rail tab on desktop, and the rail is wider
The handoff drew the toolkit as a 216px card left of the plan. That width was better spent on the plan and the rail, so the toolkit is now the rail's first tab — Toolkit / Plot / Journal / History / Assistant — rendered `embedded` (no card chrome, no heading; the tab is the heading), the grid is two columns, and the rail grows from 336 to 400px. Focusing a bed (double-click) switches the rail to Toolkit, because that is where the plant palette now lives; a single click still selects into Plot. The phone chrome is untouched: it never used the card. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
@@ -132,7 +132,7 @@ React 19 + TypeScript + Vite + Tailwind 4 (`@tailwindcss/vite`), `@tanstack/reac
|
||||
- **Routes:** `/login`, `/register`, `/gardens` (list), `/gardens/:id` (editor, `?focus=objectId`), `/plants` (catalog), `/settings` (admin), `/g/:token` (public read-only). Auth guard on the router root via `/auth/me`. Every page renders its own nav; the root shell is only a Suspense boundary plus the toast stack.
|
||||
- **State:** TanStack Query for all server state (editor keyed on `gardens/:id/full`; optimistic mutations with version-conflict rollback). One Zustand store (`web/src/editor/store.ts`) for ephemeral editor state only: camera `{tx, ty, s}`, selection, focused bed, the armed kind or plant (+ seed lot), rail tab, phone mode, journal scope, in-flight drag geometry.
|
||||
- **The canvas (`web/src/editor/Canvas.tsx`)** is one SVG with one `translate/scale` group and its own pointer-event model (above). Object drags snap their center to a 3″ grid (the garden's own grid when it snaps) and commit ONE PATCH on release; plops drag in their bed's local frame and may overhang its edge by half their radius (the spacing rule). Fit and focus animate through a CSS transition on the group; drags and zooms don't. Corner handles on the selected object resize it — the one addition to the prototype, since the kinds' fixed default sizes can't make a 2′×8′ bed. Tap-to-place makes a one-plant plop (radius = spacing/2); "Fill the bed" (rows or clumps, `POST /objects/:id/fill`) is how you plant in bulk.
|
||||
- **Two chromes, one tree.** The editor measures its own container: ≥ 760px is the desktop workspace (toolkit 216px | plan | rail 336px, the rail's Plot/Journal/History/Assistant tabs); below it the phone layout — header, full-screen canvas, an in-flow **peek** (≤ 45% tall, docked between the canvas and the mode bar) for the inspector, journal or assistant, a tool strip for Build or Plants mode, and the always-visible mode bar. Focusing a bed on the phone switches to Plants mode; a plant can also be tapped straight into any bed without focusing.
|
||||
- **Two chromes, one tree.** The editor measures its own container: ≥ 760px is the desktop workspace (plan | rail 400px, the rail's Toolkit/Plot/Journal/History/Assistant tabs — the toolkit was the handoff's 216px left card until 2026-08-23, and folding it into the rail gave the plan and the rail the width; focusing a bed switches the rail to Toolkit, selecting one switches it to Plot); below it the phone layout — header, full-screen canvas, an in-flow **peek** (≤ 45% tall, docked between the canvas and the mode bar) for the inspector, journal or assistant, a tool strip for Build or Plants mode, and the always-visible mode bar. Focusing a bed on the phone switches to Plants mode; a plant can also be tapped straight into any bed without focusing.
|
||||
- **Plant markers** are the plant's color plus a monogram derived from its name (`web/src/lib/monogram.ts`, collisions resolved across the whole catalog so a letter means the same thing on every screen).
|
||||
- **Undo** in the editor's header reverts the newest change set still in effect (not already reverted, not itself a revert) — after re-reading the history, because the cached list trails the canvas right after a placement, and undoing the step *before* the one you meant is the worst thing an undo button can do. The History tab offers every step, including undoing an undo.
|
||||
- **Seasons** are the years with planting data (`GET /gardens/:id/years`); the current year is live, any other is read-only. A *plan* is a whole-garden copy named `<garden> — <year>` (`web/src/lib/plan.ts`); the season control lists a garden's plan copies and, from inside one, the way back. The name is the only link the API keeps, which is deliberate — rename the copy and it is simply a garden.
|
||||
|
||||
Reference in New Issue
Block a user