From 2cdd283027ae7b704d16b894c9b86d63d55431e9 Mon Sep 17 00:00:00 2001 From: Cam Pedersen Date: Fri, 5 Jun 2026 15:26:09 -0400 Subject: [PATCH 1/2] fix(onboarding): "Start blank" gives a truly empty canvas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handleStartBlank() created a 20×20×20 cube despite the action being labelled "empty canvas" (and the footer koan reading "an empty canvas is potential"), so every new-from-blank user got a stray cube to delete. Drop the addPrimitive + select + transform-mode calls; just dismiss the onboarding. Removes the now unused store hooks. Found while dogfooding circuit creation (File → New → Start blank). Co-Authored-By: Claude Opus 4.8 --- packages/app/src/components/InlineOnboarding.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/app/src/components/InlineOnboarding.tsx b/packages/app/src/components/InlineOnboarding.tsx index a25b3300..5367054e 100644 --- a/packages/app/src/components/InlineOnboarding.tsx +++ b/packages/app/src/components/InlineOnboarding.tsx @@ -15,7 +15,7 @@ import { Waveform } from "@phosphor-icons/react/dist/ssr/Waveform"; import { Star } from "@phosphor-icons/react/dist/ssr/Star"; import type { Icon } from "@phosphor-icons/react"; import { cn } from "@/lib/utils"; -import { useDocumentStore, useUiStore, useChatStore, parseVcadFile } from "@vcad/core"; +import { useDocumentStore, useChatStore, parseVcadFile } from "@vcad/core"; import { useAuth, isAuthEnabled, AuthModal } from "@vcad/auth"; import { useOnboardingStore } from "@/stores/onboarding-store"; import { examples, exampleToVcadFile } from "@/data/examples"; @@ -51,9 +51,6 @@ export function InlineOnboarding({ visible }: InlineOnboardingProps) { const fileInputRef = useRef(null); const loadDocument = useDocumentStore((s) => s.loadDocument); - const addPrimitive = useDocumentStore((s) => s.addPrimitive); - const select = useUiStore((s) => s.select); - const setTransformMode = useUiStore((s) => s.setTransformMode); const setChatOpen = useChatStore((s) => s.setOpen); const incrementProjectsCreated = useOnboardingStore( (s) => s.incrementProjectsCreated, @@ -95,10 +92,8 @@ export function InlineOnboarding({ visible }: InlineOnboardingProps) { } function handleStartBlank() { + // "empty canvas" — start with a truly blank scene (no stray primitive). incrementProjectsCreated(); - const partId = addPrimitive("cube"); - select(partId); - setTransformMode("translate"); hide(); } From 76dd1e2fd3d0c3474156cf378ee8f38b652fcc50 Mon Sep 17 00:00:00 2001 From: Cam Pedersen Date: Fri, 5 Jun 2026 15:26:27 -0400 Subject: [PATCH 2/2] fix(electronics): let the wire tool connect to component pins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit onComponentClick unconditionally called e.stopPropagation() + selected the component, regardless of the active tool. With the Wire tool active, clicking a component's pin therefore selected the part instead of letting the canvas wire handler (onSvgClick) snap a wire to that pin — so you couldn't start or finish a wire on a pin by clicking it, the most natural gesture. Wiring only worked by clicking empty grid near a pin, defeating the pin-snap entirely. Now wire-mode clicks fall through to the canvas so they snap to the pin. Found while dogfooding: building an LED + resistor circuit, every wire attempt just selected the component. After the fix, VCC→R1→D1→GND wires cleanly to ERC 0. Co-Authored-By: Claude Opus 4.8 --- packages/app/src/components/electronics/SchematicCanvas.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/app/src/components/electronics/SchematicCanvas.tsx b/packages/app/src/components/electronics/SchematicCanvas.tsx index 2b11d57b..0b4a11fd 100644 --- a/packages/app/src/components/electronics/SchematicCanvas.tsx +++ b/packages/app/src/components/electronics/SchematicCanvas.tsx @@ -605,6 +605,10 @@ export function SchematicCanvas() { const onComponentClick = useCallback( (e: React.MouseEvent, idx: number, ref: string) => { + // Wire tool: let the click fall through to the canvas handler so it snaps + // to this component's pin — clicking a pin should start/finish a wire, not + // select the part. (Without this, stopPropagation swallows the wire click.) + if (schTool === "wire") return; e.stopPropagation(); if (schTool === "delete") { removeSchematicComponent(idx);