Skip to content

nodes: improve modular cabinet constraints and finishes - #719

Open
sudhir9297 wants to merge 59 commits into
pascalorg:mainfrom
sudhir9297:t3code/improve-kitchen-cabinets
Open

nodes: improve modular cabinet constraints and finishes#719
sudhir9297 wants to merge 59 commits into
pascalorg:mainfrom
sudhir9297:t3code/improve-kitchen-cabinets

Conversation

@sudhir9297

@sudhir9297 sudhir9297 commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

  • Improves modular cabinet sizing with metric and US dimension profiles, standard widths, reveal presets, planning validation, and configurable top-cabinet or trim ceiling finishes.
  • Reworks constrained run reflow so wider appliance presets consume available wall slack or resize eligible neighboring base cabinets while preserving two-wall extents.
  • Keeps L-shaped corner runs governed by the original straight run's perpendicular-wall constraints, resynchronizes derived corner geometry after width changes, and rejects changes only when real donor capacity is insufficient.
  • Adds focused coverage for straight, nested, chained, one-wall, two-wall, and two-ended L-run scenarios, plus cabinet finish and sizing behavior.

How to test

  1. Run bun dev, open the editor, and create a straight modular base-cabinet run with perpendicular walls constraining both ends.
  2. Add an L Left or L Right return at either end, then change a center or end module to a wider refrigerator preset. Confirm the original straight run keeps its wall-bounded extent, eligible base cabinets absorb the width change, and the L return stays inside the walls.
  3. Switch the refrigerator back to a narrower preset. Confirm donated widths are restored and the L footprint remains anchored.
  4. Remove one of the original run's perpendicular end walls and repeat the width changes. Confirm available wall slack is consumed first and the run moves only toward the open side without treating the derived L-leg wall as a source-run constraint.
  5. Repeat with L returns on both ends and with a nested L-leg selected. Confirm constraints still come from the original straight run and valid refrigerator changes do not report “No space in this run.”
  6. In the cabinet panels, verify standard dimensions, module widths, reveal gaps, planning warnings, and Top / Ceiling controls. Apply Top Cabinet and Trim / Soffit finishes and use Fill to ceiling.
  7. Run bun test packages/nodes/src/cabinet, bun run check-types, bun run check, and bun run build.

Screenshots / screen recording

To be added — this is a visual and interactive cabinet-layout change.

Checklist

  • I've tested this locally with bun dev
  • My code follows the existing code style (run bun check to verify)
  • I've updated relevant documentation (if applicable)
  • This PR targets the main branch

Note

Medium Risk
Touches cabinet schema, graph acceptance, and shared 2D/3D move/snap behavior used beyond cabinets; regressions could affect placement, dragging, and saved graphs with nested cabinet runs.

Overview
Modular cabinets get metric-first defaults (CABINET_METRIC_DEFAULTS), optional top-cabinet / trim finishes, runs that can nest derived L-corner child runs, and stricter graph validation for that shape. Cabinet kinds opt into plain body drag, footprint-aware grid snap, and wall attach that can set yaw; run reflow, corner geometry, appliance widths, and panel rules are tightened with broad new tests.

The editor move pipeline is reworked so wall attachment runs before grid/alignment, registry tools can receive raw floorplan grid points (so attachment wins), 2D previews use rigid translate+rotate, and R/T rotation is blocked while wall-attached. Direct manipulation is generalized via shouldStartDirectMoveDrag, handle hit detection, and move routing through resolveMoveActionNode / resolveDirectManipulationNode.

Build tab adds a Kitchen group that arms the modular cabinet catalog tool. Roof drops the legacy RoofTool / RoofHelper path in favor of registry tooling. Core exports conical-roof helpers removed; tool hints can be gated with optional visible predicates.

Reviewed by Cursor Bugbot for commit adce08a. Bugbot is set up for automated code reviews on this repo. Configure here.

sudhir9297 and others added 30 commits May 19, 2026 02:59
Items (e.g. solar panels) can now be placed on sloped roof surfaces.
The placement system computes euler rotation from the roof surface
normal so items sit flush on the slope instead of going inside.

- Add roofStrategy to placement-strategies with enter/move/click/leave
- Wire roof:enter/move/click/leave events in the placement coordinator
- Add calculateRoofRotation in placement-math using surface normals
- Support full 3D cursor rotation for sloped surfaces
- Items on roofs are parented to the level with world-space rotation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/nodes/src/cabinet/run-ops.ts Outdated
Comment thread packages/nodes/src/cabinet/definition.ts
Comment thread packages/nodes/src/cabinet/panel.tsx Outdated
Comment thread packages/nodes/src/cabinet/definition.ts
Comment thread packages/nodes/src/cabinet/run-panel.tsx
Comment thread packages/nodes/src/cabinet/panel.tsx

@Aymericr Aymericr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one I like — thanks. 40 files, all but three inside packages/nodes/src/cabinet/, and 2,910 of the 4,864 added lines are tests. It's mergeable against main and it doesn't collide with anything that landed in the last two weeks. Small pure modules (validation.ts, profiles.ts, widths.ts, reveals.ts, panel-visibility.ts) with unit tests each is exactly the shape I want cabinet work to take. Three things before I merge:

1. The nested L-leg reflow axis (Bugbot High). In run-panel.tsx the wall constraints are read from the source straight run and then applied as left/right flags while packing the leg's own local X. For a one-wall source, the perpendicular return grows and consumes slack along the source's lateral axis, so it can shift the wrong way. Worth a test with a one-wall source and an L return.

2. Make topFinish a first-class volume everywhere, in one pass. cabinetLocalBounds and includeCabinetModuleBounds now include topFinishHeight, but floor-placed footprints still size height with cabinetTotalHeight, so collision and placement treat the finish as empty air. In the same pass: cabinetCeilingGap floors at 0.05 even when the module already reaches the ceiling, and fill-to-ceiling writes that value straight into topFinishHeight without the schema's 1.2 cap — so a tall room can push a finish through the ceiling and out of range. And validateCabinetRun only visits the parent run's direct modules, so nested wall cabinets (the ones that actually use Top / Trim) never get top-cabinet-too-short. While you're in there, topFinishHeight ?? 0.33 appears as a literal in two places in definition.ts — the schema already defaults it, so lean on that.

3. Move the research docs. docs/research/cabinet-ceiling-gap.md and docs/research/modular-kitchen-cabinets.md would create a new top-level docs/ tree in the public repo; research and planning notes don't live here. Drop them from the PR and send them my way, or fold anything durable into wiki/architecture/ as "how it works now".

Two things I want to confirm rather than change: the new metric defaults put base cabinets at 600 deep / 800 carcass, which lands the worktop around 920 mm and also moves wall cabinets from 720 to 800 — I read that as deliberately the METOD family rather than the 720+150+30 convention, so just confirm and I'm happy. And widening CabinetNode.children to allow a nested cabinet is a real scene-graph shape change; the graph-schema test covers parsing, and the three points above are exactly the code that doesn't walk it yet — which is why I'd like them in before merge rather than after.

Fix those and I'll merge this ahead of #718.

Comment thread packages/nodes/src/cabinet/run-panel.tsx Outdated
Comment thread packages/nodes/src/cabinet/run-ops.ts
Comment thread packages/nodes/src/cabinet/definition.ts
Comment thread packages/nodes/src/cabinet/run-panel.tsx
Comment thread packages/editor/src/components/editor/handles/handle-arrow.tsx Outdated
Comment thread packages/editor/src/lib/direct-manipulation.ts
Comment thread packages/nodes/src/cabinet/panel.tsx
Comment thread packages/nodes/src/cabinet/panel.tsx Outdated
Comment thread packages/nodes/src/cabinet/definition.ts
Comment thread packages/nodes/src/cabinet/panel-context.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit adce08a. Configure here.

</PanelSection>
)}

{canAddTopFinish && (

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nested walls get run-level actions

High Severity

cabinetModulePanelContext now walks to the ancestor cabinet run for nested wall modules, but the Cabinet Type section still keys off parentRun alone. A selected wall cabinet therefore shows Base/Tall, Add wall cabinet, and Add chimney, and those actions call switchCabinetToTall, switchCabinetToBase, and addWallChildAbove with a run that is not the module's parent. That can restack or reparent a wall unit and break its elevation.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit adce08a. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants