From 08d9899bae78a87af9a9be4d461a9fe2ed294b8d Mon Sep 17 00:00:00 2001 From: Ayush Jhawar <111112495+Ayushjhawar8@users.noreply.github.com> Date: Wed, 12 Nov 2025 23:01:44 +0530 Subject: [PATCH] Add pcb_panel center handling --- lib/components/normal-components/Panel.ts | 46 +++++++++++++++++++ package.json | 2 +- .../normal-components/panel.test.tsx | 35 ++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/lib/components/normal-components/Panel.ts b/lib/components/normal-components/Panel.ts index fa492e834..681f28f35 100644 --- a/lib/components/normal-components/Panel.ts +++ b/lib/components/normal-components/Panel.ts @@ -1,8 +1,11 @@ import { panelProps } from "@tscircuit/props" +import { distance } from "circuit-json" import type { PrimitiveComponent } from "../base-components/PrimitiveComponent" import { Group } from "../primitive-components/Group/Group" export class Panel extends Group { + pcb_panel_id: string | null = null + get config() { return { componentName: "Panel", @@ -14,6 +17,10 @@ export class Panel extends Group { return true } + get isSubcircuit() { + return true + } + add(component: PrimitiveComponent) { if (component.lowercaseComponentName !== "board") { throw new Error(" can only contain elements") @@ -28,4 +35,43 @@ export class Panel extends Group { super.runRenderCycle() } + + doInitialPcbComponentRender() { + super.doInitialPcbComponentRender() + if (this.root?.pcbDisabled) return + + const { db } = this.root! + const props = this._parsedProps + + const inserted = db.pcb_panel.insert({ + width: distance.parse(props.width), + height: distance.parse(props.height), + center: this._getGlobalPcbPositionBeforeLayout(), + covered_with_solder_mask: !(props.noSolderMask ?? false), + }) + + this.pcb_panel_id = inserted.pcb_panel_id + } + + updatePcbComponentRender() { + if (this.root?.pcbDisabled) return + if (!this.pcb_panel_id) return + + const { db } = this.root! + const props = this._parsedProps + + db.pcb_panel.update(this.pcb_panel_id, { + width: distance.parse(props.width), + height: distance.parse(props.height), + center: this._getGlobalPcbPositionBeforeLayout(), + covered_with_solder_mask: !(props.noSolderMask ?? false), + }) + } + + removePcbComponentRender() { + if (!this.pcb_panel_id) return + + this.root?.db.pcb_panel.delete(this.pcb_panel_id) + this.pcb_panel_id = null + } } diff --git a/package.json b/package.json index cfae54511..fb42959dc 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "bun-match-svg": "0.0.12", "calculate-elbow": "^0.0.12", "chokidar-cli": "^3.0.0", - "circuit-json": "^0.0.306", + "circuit-json": "^0.0.307", "circuit-json-to-bpc": "^0.0.13", "circuit-json-to-connectivity-map": "^0.0.22", "circuit-json-to-gltf": "^0.0.31", diff --git a/tests/components/normal-components/panel.test.tsx b/tests/components/normal-components/panel.test.tsx index 1b1133112..a39d0000a 100644 --- a/tests/components/normal-components/panel.test.tsx +++ b/tests/components/normal-components/panel.test.tsx @@ -66,3 +66,38 @@ test("panel must contain at least one board", () => { circuit.render() }).toThrow(" must contain at least one ") }) + +test("panel emits pcb_panel with center", () => { + const { circuit } = getTestFixture() + + circuit.add( + + + , + ) + + circuit.render() + + const pcbPanel = circuit.db.pcb_panel.list()[0] + expect(pcbPanel).toMatchObject({ + width: 100, + height: 50, + center: { x: 10, y: 20 }, + covered_with_solder_mask: true, + }) +}) + +test("panel noSolderMask disables solder mask coverage", () => { + const { circuit } = getTestFixture() + + circuit.add( + + + , + ) + + circuit.render() + + const pcbPanel = circuit.db.pcb_panel.list()[0] + expect(pcbPanel.covered_with_solder_mask).toBe(false) +})