@tscircuit/core 0.0.1073 → 0.0.1074

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -512,6 +512,11 @@ declare abstract class PrimitiveComponent<ZodProps extends ZodType = any> extend
512
512
  private _shouldAllowBoardVariablesByDefault;
513
513
  private _isInsideFootprint;
514
514
  private _isInsideNonBoardSubcircuit;
515
+ /**
516
+ * Check if this component has a user-defined PCB position.
517
+ * Position can be specified via pcbX/pcbY or edge-based props.
518
+ */
519
+ _hasUserDefinedPcbPosition(): boolean;
515
520
  resolvePcbCoordinate(rawValue: unknown, axis: "pcbX" | "pcbY", options?: {
516
521
  allowBoardVariables?: boolean;
517
522
  allowComponentVariables?: boolean;
@@ -6112,6 +6117,11 @@ declare class Subpanel extends Group<typeof subpanelProps> {
6112
6117
  add(component: PrimitiveComponent): void;
6113
6118
  _cachedGridWidth: number;
6114
6119
  _cachedGridHeight: number;
6120
+ _panelPositionOffset: {
6121
+ x: number;
6122
+ y: number;
6123
+ } | null;
6124
+ _computePcbGlobalTransformBeforeLayout(): Matrix;
6115
6125
  /**
6116
6126
  * Get all board instances from this subpanel and nested subpanels
6117
6127
  */
package/dist/index.js CHANGED
@@ -1285,6 +1285,14 @@ var PrimitiveComponent2 = class extends Renderable {
1285
1285
  }
1286
1286
  return false;
1287
1287
  }
1288
+ /**
1289
+ * Check if this component has a user-defined PCB position.
1290
+ * Position can be specified via pcbX/pcbY or edge-based props.
1291
+ */
1292
+ _hasUserDefinedPcbPosition() {
1293
+ const props = this._parsedProps;
1294
+ return props.pcbX !== void 0 || props.pcbY !== void 0 || props.pcbLeftEdgeX !== void 0 || props.pcbRightEdgeX !== void 0 || props.pcbTopEdgeY !== void 0 || props.pcbBottomEdgeY !== void 0;
1295
+ }
1288
1296
  resolvePcbCoordinate(rawValue, axis, options = {}) {
1289
1297
  return this._resolvePcbCoordinate(rawValue, axis, options);
1290
1298
  }
@@ -18094,7 +18102,7 @@ import { identity as identity5 } from "transformation-matrix";
18094
18102
  var package_default = {
18095
18103
  name: "@tscircuit/core",
18096
18104
  type: "module",
18097
- version: "0.0.1072",
18105
+ version: "0.0.1073",
18098
18106
  types: "dist/index.d.ts",
18099
18107
  main: "dist/index.js",
18100
18108
  module: "dist/index.js",
@@ -18128,7 +18136,7 @@ var package_default = {
18128
18136
  "@tscircuit/alphabet": "0.0.18",
18129
18137
  "@tscircuit/capacity-autorouter": "^0.0.299",
18130
18138
  "@tscircuit/checks": "0.0.100",
18131
- "@tscircuit/circuit-json-util": "^0.0.80",
18139
+ "@tscircuit/circuit-json-util": "^0.0.81",
18132
18140
  "@tscircuit/common": "^0.0.20",
18133
18141
  "@tscircuit/copper-pour-solver": "^0.0.20",
18134
18142
  "@tscircuit/footprinter": "^0.0.316",
@@ -19213,6 +19221,7 @@ import { distance as distance12 } from "circuit-json";
19213
19221
  // lib/components/normal-components/Subpanel.ts
19214
19222
  import { subpanelProps } from "@tscircuit/props";
19215
19223
  import { distance as distance11 } from "circuit-json";
19224
+ import { compose as compose8, identity as identity6, translate as translate8 } from "transformation-matrix";
19216
19225
 
19217
19226
  // lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
19218
19227
  import * as Flatten from "@flatten-js/core";
@@ -19423,7 +19432,7 @@ function generatePanelTabsAndMouseBites(boards, options) {
19423
19432
  };
19424
19433
  }
19425
19434
 
19426
- // lib/utils/panels/pack-boards-into-grid.ts
19435
+ // lib/utils/panels/pack-into-grid.ts
19427
19436
  import { distance as distance10 } from "circuit-json";
19428
19437
 
19429
19438
  // lib/utils/panels/get-board-dimensions-from-props.ts
@@ -19455,52 +19464,9 @@ var getBoardDimensionsFromProps = (board) => {
19455
19464
  };
19456
19465
  };
19457
19466
 
19458
- // lib/utils/panels/pack-boards-into-grid.ts
19459
- function calculateOptimalGrid({
19460
- boardsWithDims,
19461
- availableWidth,
19462
- availableHeight,
19463
- boardGap,
19464
- minCellWidth,
19465
- minCellHeight
19466
- }) {
19467
- const boardCount = boardsWithDims.length;
19468
- if (boardCount === 0) {
19469
- return { rows: 0, cols: 0 };
19470
- }
19471
- const maxBoardWidth = Math.max(
19472
- ...boardsWithDims.map((b) => b.width),
19473
- minCellWidth
19474
- );
19475
- const maxBoardHeight = Math.max(
19476
- ...boardsWithDims.map((b) => b.height),
19477
- minCellHeight
19478
- );
19479
- const maxCols = Math.max(
19480
- 1,
19481
- Math.floor((availableWidth + boardGap) / (maxBoardWidth + boardGap))
19482
- );
19483
- const maxRows = Math.max(
19484
- 1,
19485
- Math.floor((availableHeight + boardGap) / (maxBoardHeight + boardGap))
19486
- );
19487
- let bestCols = maxCols;
19488
- let bestRows = Math.ceil(boardCount / bestCols);
19489
- if (bestRows > maxRows) {
19490
- bestRows = maxRows;
19491
- bestCols = Math.ceil(boardCount / bestRows);
19492
- if (bestCols > maxCols) {
19493
- bestCols = maxCols;
19494
- bestRows = Math.ceil(boardCount / bestCols);
19495
- }
19496
- }
19497
- return {
19498
- rows: Math.max(1, bestRows),
19499
- cols: Math.max(1, bestCols)
19500
- };
19501
- }
19502
- var packBoardsIntoGrid = ({
19503
- boards,
19467
+ // lib/utils/panels/pack-into-grid.ts
19468
+ function packIntoGrid({
19469
+ items,
19504
19470
  db,
19505
19471
  row,
19506
19472
  col,
@@ -19509,109 +19475,161 @@ var packBoardsIntoGrid = ({
19509
19475
  boardGap,
19510
19476
  availablePanelWidth,
19511
19477
  availablePanelHeight
19512
- }) => {
19513
- const boardsWithDims = boards.map((board) => {
19514
- let width;
19515
- let height;
19516
- if (db && board.pcb_board_id) {
19517
- const pcbBoard = db.pcb_board.get(board.pcb_board_id);
19518
- if (pcbBoard?.width !== void 0 && pcbBoard?.height !== void 0) {
19519
- width = pcbBoard.width;
19520
- height = pcbBoard.height;
19521
- }
19522
- }
19523
- if (width === void 0 || height === void 0) {
19524
- const propsDims = getBoardDimensionsFromProps(board);
19525
- width = propsDims.width;
19526
- height = propsDims.height;
19527
- }
19528
- if (width === 0 && height === 0) {
19529
- return null;
19530
- }
19531
- return { board, width, height };
19532
- }).filter((b) => b !== null);
19533
- if (boardsWithDims.length === 0) {
19534
- return {
19535
- positions: [],
19536
- gridWidth: 0,
19537
- gridHeight: 0
19538
- };
19478
+ }) {
19479
+ const itemsWithDims = items.map((item) => {
19480
+ const dims = getItemDimensions(item, db);
19481
+ return { item, width: dims.width, height: dims.height };
19482
+ }).filter((item) => !(item.width === 0 && item.height === 0));
19483
+ if (itemsWithDims.length === 0) {
19484
+ return { positions: [], gridWidth: 0, gridHeight: 0 };
19539
19485
  }
19540
- const explicitRow = row;
19541
- const explicitCol = col;
19542
19486
  let cols;
19543
19487
  let rows;
19544
- if (explicitCol !== void 0) {
19545
- cols = explicitCol;
19546
- rows = explicitRow ?? Math.ceil(boardsWithDims.length / cols);
19547
- } else if (explicitRow !== void 0) {
19548
- rows = explicitRow;
19549
- cols = Math.ceil(boardsWithDims.length / rows);
19488
+ const minCellWidth = cellWidth ? distance10.parse(cellWidth) : 0;
19489
+ const minCellHeight = cellHeight ? distance10.parse(cellHeight) : 0;
19490
+ if (col !== void 0) {
19491
+ cols = col;
19492
+ rows = row ?? Math.ceil(itemsWithDims.length / cols);
19493
+ } else if (row !== void 0) {
19494
+ rows = row;
19495
+ cols = Math.ceil(itemsWithDims.length / rows);
19550
19496
  } else if (availablePanelWidth !== void 0 && availablePanelHeight !== void 0) {
19551
- const result = calculateOptimalGrid({
19552
- boardsWithDims,
19553
- availableWidth: availablePanelWidth,
19554
- availableHeight: availablePanelHeight,
19555
- boardGap,
19556
- minCellWidth: cellWidth ? distance10.parse(cellWidth) : 0,
19557
- minCellHeight: cellHeight ? distance10.parse(cellHeight) : 0
19558
- });
19559
- cols = result.cols;
19560
- rows = result.rows;
19497
+ const maxItemWidth = Math.max(
19498
+ ...itemsWithDims.map((b) => b.width),
19499
+ minCellWidth
19500
+ );
19501
+ const maxItemHeight = Math.max(
19502
+ ...itemsWithDims.map((b) => b.height),
19503
+ minCellHeight
19504
+ );
19505
+ const maxCols = Math.max(
19506
+ 1,
19507
+ Math.floor((availablePanelWidth + boardGap) / (maxItemWidth + boardGap))
19508
+ );
19509
+ const maxRows = Math.max(
19510
+ 1,
19511
+ Math.floor(
19512
+ (availablePanelHeight + boardGap) / (maxItemHeight + boardGap)
19513
+ )
19514
+ );
19515
+ cols = maxCols;
19516
+ rows = Math.ceil(itemsWithDims.length / cols);
19517
+ if (rows > maxRows) {
19518
+ rows = maxRows;
19519
+ cols = Math.ceil(itemsWithDims.length / rows);
19520
+ if (cols > maxCols) {
19521
+ cols = maxCols;
19522
+ rows = Math.ceil(itemsWithDims.length / cols);
19523
+ }
19524
+ }
19525
+ cols = Math.max(1, cols);
19526
+ rows = Math.max(1, rows);
19561
19527
  } else {
19562
- cols = Math.ceil(Math.sqrt(boardsWithDims.length));
19563
- rows = Math.ceil(boardsWithDims.length / cols);
19528
+ cols = Math.ceil(Math.sqrt(itemsWithDims.length));
19529
+ rows = Math.ceil(itemsWithDims.length / cols);
19564
19530
  }
19565
19531
  const colWidths = Array(cols).fill(0);
19566
19532
  const rowHeights = Array(rows).fill(0);
19567
- boardsWithDims.forEach((b, i) => {
19533
+ itemsWithDims.forEach((item, i) => {
19568
19534
  const colIdx = i % cols;
19569
19535
  const rowIdx = Math.floor(i / cols);
19570
- if (rowIdx < rowHeights.length && b.height > rowHeights[rowIdx]) {
19571
- rowHeights[rowIdx] = b.height;
19536
+ if (rowIdx < rowHeights.length && item.height > rowHeights[rowIdx]) {
19537
+ rowHeights[rowIdx] = item.height;
19572
19538
  }
19573
- if (colIdx < colWidths.length && b.width > colWidths[colIdx]) {
19574
- colWidths[colIdx] = b.width;
19539
+ if (colIdx < colWidths.length && item.width > colWidths[colIdx]) {
19540
+ colWidths[colIdx] = item.width;
19575
19541
  }
19576
19542
  });
19577
- const minCellWidth = cellWidth ? distance10.parse(cellWidth) : 0;
19578
- const minCellHeight = cellHeight ? distance10.parse(cellHeight) : 0;
19579
19543
  for (let i = 0; i < colWidths.length; i++) {
19580
19544
  colWidths[i] = Math.max(colWidths[i], minCellWidth);
19581
19545
  }
19582
19546
  for (let i = 0; i < rowHeights.length; i++) {
19583
19547
  rowHeights[i] = Math.max(rowHeights[i], minCellHeight);
19584
19548
  }
19585
- const totalGridWidth = colWidths.reduce((a, b) => a + b, 0) + (cols > 1 ? (cols - 1) * boardGap : 0);
19586
- const totalGridHeight = rowHeights.reduce((a, b) => a + b, 0) + (rows > 1 ? (rows - 1) * boardGap : 0);
19587
- const startX = -totalGridWidth / 2;
19588
- const startY = -totalGridHeight / 2;
19589
- const rowYOffsets = [startY];
19590
- for (let i = 1; i < rows; i++) {
19591
- rowYOffsets.push(rowYOffsets[i - 1] + rowHeights[i - 1] + boardGap);
19592
- }
19549
+ const gridWidth = colWidths.reduce((a, b) => a + b, 0) + (cols > 1 ? (cols - 1) * boardGap : 0);
19550
+ const gridHeight = rowHeights.reduce((a, b) => a + b, 0) + (rows > 1 ? (rows - 1) * boardGap : 0);
19551
+ const startX = -gridWidth / 2;
19552
+ const startY = -gridHeight / 2;
19593
19553
  const colXOffsets = [startX];
19594
19554
  for (let i = 1; i < cols; i++) {
19595
19555
  colXOffsets.push(colXOffsets[i - 1] + colWidths[i - 1] + boardGap);
19596
19556
  }
19557
+ const rowYOffsets = [startY];
19558
+ for (let i = 1; i < rows; i++) {
19559
+ rowYOffsets.push(rowYOffsets[i - 1] + rowHeights[i - 1] + boardGap);
19560
+ }
19597
19561
  const positions = [];
19598
- boardsWithDims.forEach((b, i) => {
19562
+ itemsWithDims.forEach((itemWithDims, i) => {
19599
19563
  const colIdx = i % cols;
19600
19564
  const rowIdx = Math.floor(i / cols);
19601
19565
  if (rowIdx >= rowYOffsets.length || colIdx >= colXOffsets.length) return;
19602
- const cellX = colXOffsets[colIdx];
19603
- const cellY = rowYOffsets[rowIdx];
19604
- const currentCellWidth = colWidths[colIdx];
19605
- const currentCellHeight = rowHeights[rowIdx];
19606
- const boardX = cellX + currentCellWidth / 2;
19607
- const boardY = cellY + currentCellHeight / 2;
19608
- positions.push({
19609
- board: b.board,
19610
- pos: { x: boardX, y: boardY }
19611
- });
19566
+ const x = colXOffsets[colIdx] + colWidths[colIdx] / 2;
19567
+ const y = rowYOffsets[rowIdx] + rowHeights[rowIdx] / 2;
19568
+ positions.push({ item: itemWithDims.item, pos: { x, y } });
19612
19569
  });
19613
- return { positions, gridWidth: totalGridWidth, gridHeight: totalGridHeight };
19614
- };
19570
+ return { positions, gridWidth, gridHeight };
19571
+ }
19572
+ function getItemDimensions(item, db) {
19573
+ if (item.componentName === "Board") {
19574
+ const board = item;
19575
+ if (db && board.pcb_board_id) {
19576
+ const pcbBoard = db.pcb_board.get(board.pcb_board_id);
19577
+ if (pcbBoard?.width !== void 0 && pcbBoard?.height !== void 0) {
19578
+ return { width: pcbBoard.width, height: pcbBoard.height };
19579
+ }
19580
+ }
19581
+ return getBoardDimensionsFromProps(board);
19582
+ }
19583
+ if (item.componentName === "Subpanel") {
19584
+ const subpanel = item;
19585
+ const props = subpanel._parsedProps;
19586
+ if (props.width !== void 0 && props.height !== void 0) {
19587
+ return {
19588
+ width: distance10.parse(props.width),
19589
+ height: distance10.parse(props.height)
19590
+ };
19591
+ }
19592
+ const directBoards = subpanel._getDirectBoardChildren();
19593
+ if (directBoards.length === 0) {
19594
+ const allBoards = subpanel._getAllBoardInstances();
19595
+ if (allBoards.length === 0) return { width: 0, height: 0 };
19596
+ let minX = Infinity;
19597
+ let minY = Infinity;
19598
+ let maxX = -Infinity;
19599
+ let maxY = -Infinity;
19600
+ for (const board of allBoards) {
19601
+ const dims = getBoardDimensionsFromProps(board);
19602
+ if (dims.width === 0 || dims.height === 0) continue;
19603
+ const offset = board._panelPositionOffset ?? { x: 0, y: 0 };
19604
+ minX = Math.min(minX, offset.x - dims.width / 2);
19605
+ maxX = Math.max(maxX, offset.x + dims.width / 2);
19606
+ minY = Math.min(minY, offset.y - dims.height / 2);
19607
+ maxY = Math.max(maxY, offset.y + dims.height / 2);
19608
+ }
19609
+ if (minX === Infinity) return { width: 0, height: 0 };
19610
+ return { width: maxX - minX, height: maxY - minY };
19611
+ }
19612
+ if (directBoards.length === 1) {
19613
+ return getBoardDimensionsFromProps(directBoards[0]);
19614
+ }
19615
+ if (subpanel._cachedGridWidth > 0 && subpanel._cachedGridHeight > 0) {
19616
+ const edgePadding = distance10.parse(props.edgePadding ?? 5);
19617
+ return {
19618
+ width: subpanel._cachedGridWidth + edgePadding * 2,
19619
+ height: subpanel._cachedGridHeight + edgePadding * 2
19620
+ };
19621
+ }
19622
+ let totalWidth = 0;
19623
+ let totalHeight = 0;
19624
+ for (const board of directBoards) {
19625
+ const dims = getBoardDimensionsFromProps(board);
19626
+ totalWidth = Math.max(totalWidth, dims.width);
19627
+ totalHeight = Math.max(totalHeight, dims.height);
19628
+ }
19629
+ return { width: totalWidth, height: totalHeight };
19630
+ }
19631
+ return { width: 0, height: 0 };
19632
+ }
19615
19633
 
19616
19634
  // lib/components/normal-components/Subpanel.ts
19617
19635
  var Subpanel = class _Subpanel extends Group6 {
@@ -19642,6 +19660,17 @@ var Subpanel = class _Subpanel extends Group6 {
19642
19660
  }
19643
19661
  _cachedGridWidth = 0;
19644
19662
  _cachedGridHeight = 0;
19663
+ _panelPositionOffset = null;
19664
+ _computePcbGlobalTransformBeforeLayout() {
19665
+ if (this._panelPositionOffset) {
19666
+ const parentTransform = this.parent?._computePcbGlobalTransformBeforeLayout?.() ?? identity6();
19667
+ return compose8(
19668
+ parentTransform,
19669
+ translate8(this._panelPositionOffset.x, this._panelPositionOffset.y)
19670
+ );
19671
+ }
19672
+ return super._computePcbGlobalTransformBeforeLayout();
19673
+ }
19645
19674
  /**
19646
19675
  * Get all board instances from this subpanel and nested subpanels
19647
19676
  */
@@ -19681,35 +19710,30 @@ var Subpanel = class _Subpanel extends Group6 {
19681
19710
  doInitialPanelBoardLayout() {
19682
19711
  if (this.root?.pcbDisabled) return;
19683
19712
  const layoutMode = this._parsedProps.layoutMode ?? "none";
19684
- const childBoardInstances = this._getDirectBoardChildren();
19713
+ const gridItems = this.children.filter(
19714
+ (c) => c instanceof Board || c instanceof _Subpanel
19715
+ );
19685
19716
  if (layoutMode !== "none") {
19686
- for (const board of childBoardInstances) {
19687
- const hasPcbX = board._parsedProps.pcbX !== void 0;
19688
- const hasPcbY = board._parsedProps.pcbY !== void 0;
19689
- if (hasPcbX || hasPcbY) {
19690
- const properties = [];
19691
- if (hasPcbX) properties.push("pcbX");
19692
- if (hasPcbY) properties.push("pcbY");
19693
- const propertyNames = properties.join(" and ");
19717
+ for (const child of gridItems) {
19718
+ if (!(child instanceof Board)) continue;
19719
+ if (child._hasUserDefinedPcbPosition()) {
19694
19720
  this.root.db.source_property_ignored_warning.insert({
19695
- source_component_id: board.source_component_id,
19696
- property_name: propertyNames,
19697
- message: `Board has manual positioning (${propertyNames}) but ${this._errorComponentName} layout mode is "${layoutMode}". Manual positioning will be ignored.`,
19721
+ source_component_id: child.source_component_id,
19722
+ property_name: "pcbX/pcbY",
19723
+ message: `Board has manual positioning but ${this._errorComponentName} layout mode is "${layoutMode}". Manual positioning will be ignored.`,
19698
19724
  error_type: "source_property_ignored_warning"
19699
19725
  });
19700
19726
  }
19701
19727
  }
19702
19728
  }
19703
- if (layoutMode === "none" && childBoardInstances.length > 1) {
19704
- const boardsWithoutPosition = childBoardInstances.filter((board) => {
19705
- const hasPcbX = board._parsedProps.pcbX !== void 0;
19706
- const hasPcbY = board._parsedProps.pcbY !== void 0;
19707
- return !hasPcbX && !hasPcbY;
19708
- });
19709
- if (boardsWithoutPosition.length > 1) {
19729
+ if (layoutMode === "none" && gridItems.length > 1) {
19730
+ const unpositionedItems = gridItems.filter(
19731
+ (c) => !c._hasUserDefinedPcbPosition()
19732
+ );
19733
+ if (unpositionedItems.length > 1) {
19710
19734
  this.root.db.pcb_placement_error.insert({
19711
19735
  error_type: "pcb_placement_error",
19712
- message: `Multiple boards in ${this._errorComponentName} without pcbX/pcbY positions. When layoutMode="none", each board must have explicit pcbX and pcbY coordinates to avoid overlapping. Either set pcbX/pcbY on each board, or use layoutMode="grid" for automatic positioning.`
19736
+ message: `Multiple boards/subpanels in ${this._errorComponentName} without positions. When layoutMode="none", each item must have explicit positioning. Use layoutMode="grid" for automatic positioning.`
19713
19737
  });
19714
19738
  }
19715
19739
  }
@@ -19743,8 +19767,8 @@ var Subpanel = class _Subpanel extends Group6 {
19743
19767
  availablePanelWidth = panelWidth - edgePaddingLeft - edgePaddingRight;
19744
19768
  availablePanelHeight = panelHeight - edgePaddingTop - edgePaddingBottom;
19745
19769
  }
19746
- const { positions, gridWidth, gridHeight } = packBoardsIntoGrid({
19747
- boards: childBoardInstances,
19770
+ const { positions, gridWidth, gridHeight } = packIntoGrid({
19771
+ items: gridItems,
19748
19772
  row: this._parsedProps.row,
19749
19773
  col: this._parsedProps.col,
19750
19774
  cellWidth: this._parsedProps.cellWidth,
@@ -19755,28 +19779,40 @@ var Subpanel = class _Subpanel extends Group6 {
19755
19779
  });
19756
19780
  this._cachedGridWidth = gridWidth;
19757
19781
  this._cachedGridHeight = gridHeight;
19758
- for (const { board, pos } of positions) {
19759
- board._panelPositionOffset = pos;
19782
+ for (const { item, pos } of positions) {
19783
+ item._panelPositionOffset = pos;
19760
19784
  }
19761
19785
  }
19762
19786
  doInitialPanelLayout() {
19763
19787
  if (this.root?.pcbDisabled) return;
19764
19788
  const { db } = this.root;
19765
- const childBoardInstances = this._getDirectBoardChildren();
19766
19789
  const layoutMode = this._parsedProps.layoutMode ?? "none";
19767
19790
  if (layoutMode === "grid") {
19768
- for (const board of childBoardInstances) {
19769
- if (!board.pcb_board_id || !board._panelPositionOffset) continue;
19770
- db.pcb_board.update(board.pcb_board_id, {
19771
- position_mode: "relative_to_panel_anchor",
19772
- display_offset_x: `${board._panelPositionOffset.x}mm`,
19773
- display_offset_y: `${board._panelPositionOffset.y}mm`
19774
- });
19791
+ for (const child of this.children) {
19792
+ if (child instanceof Board) {
19793
+ if (!child.pcb_board_id || !child._panelPositionOffset) continue;
19794
+ db.pcb_board.update(child.pcb_board_id, {
19795
+ position_mode: "relative_to_panel_anchor",
19796
+ display_offset_x: `${child._panelPositionOffset.x}mm`,
19797
+ display_offset_y: `${child._panelPositionOffset.y}mm`
19798
+ });
19799
+ } else if (child instanceof _Subpanel && child._panelPositionOffset) {
19800
+ for (const board of child._getAllBoardInstances()) {
19801
+ if (!board.pcb_board_id) continue;
19802
+ const boardOffset = board._panelPositionOffset ?? { x: 0, y: 0 };
19803
+ db.pcb_board.update(board.pcb_board_id, {
19804
+ position_mode: "relative_to_panel_anchor",
19805
+ display_offset_x: `${child._panelPositionOffset.x + boardOffset.x}mm`,
19806
+ display_offset_y: `${child._panelPositionOffset.y + boardOffset.y}mm`
19807
+ });
19808
+ }
19809
+ }
19775
19810
  }
19776
19811
  this._updatePanelDimensions();
19777
19812
  } else {
19778
19813
  const panelGlobalPos = this._getGlobalPcbPositionBeforeLayout();
19779
- for (const board of childBoardInstances) {
19814
+ for (const board of this._getDirectBoardChildren()) {
19815
+ if (!board.pcb_board_id) continue;
19780
19816
  const boardDb = db.pcb_board.get(board.pcb_board_id);
19781
19817
  if (!boardDb) continue;
19782
19818
  const relativeX = boardDb.center.x - panelGlobalPos.x;
@@ -21076,8 +21112,8 @@ var BreakoutPoint = class extends PrimitiveComponent2 {
21076
21112
  import { netLabelProps } from "@tscircuit/props";
21077
21113
  import {
21078
21114
  applyToPoint as applyToPoint19,
21079
- identity as identity6,
21080
- translate as translate8
21115
+ identity as identity7,
21116
+ translate as translate9
21081
21117
  } from "transformation-matrix";
21082
21118
  import { calculateElbow as calculateElbow2 } from "calculate-elbow";
21083
21119
  var NetLabel = class extends PrimitiveComponent2 {
@@ -21127,10 +21163,10 @@ var NetLabel = class extends PrimitiveComponent2 {
21127
21163
  if (connectedPorts.length > 0) {
21128
21164
  const portPos = connectedPorts[0]._getGlobalSchematicPositionBeforeLayout();
21129
21165
  const parentCenter = applyToPoint19(
21130
- this.parent?.computeSchematicGlobalTransform?.() ?? identity6(),
21166
+ this.parent?.computeSchematicGlobalTransform?.() ?? identity7(),
21131
21167
  { x: 0, y: 0 }
21132
21168
  );
21133
- return translate8(portPos.x - parentCenter.x, portPos.y - parentCenter.y);
21169
+ return translate9(portPos.x - parentCenter.x, portPos.y - parentCenter.y);
21134
21170
  }
21135
21171
  }
21136
21172
  return super.computeSchematicPropsTransform();
@@ -23317,7 +23353,7 @@ var SchematicCell = class extends PrimitiveComponent2 {
23317
23353
 
23318
23354
  // lib/components/primitive-components/Symbol/Symbol.ts
23319
23355
  import { symbolProps } from "@tscircuit/props";
23320
- import { compose as compose8, translate as translate9, scale as scale2 } from "transformation-matrix";
23356
+ import { compose as compose9, translate as translate10, scale as scale2 } from "transformation-matrix";
23321
23357
  var SymbolComponent = class extends PrimitiveComponent2 {
23322
23358
  isPrimitiveContainer = true;
23323
23359
  schematic_symbol_id;
@@ -23427,10 +23463,10 @@ var SymbolComponent = class extends PrimitiveComponent2 {
23427
23463
  const scaleX = targetWidth !== void 0 && currentWidth > 0 ? targetWidth / currentWidth : 1;
23428
23464
  const scaleY = targetHeight !== void 0 && currentHeight > 0 ? targetHeight / currentHeight : 1;
23429
23465
  const globalPos = this._getGlobalSchematicPositionBeforeLayout();
23430
- this.userCoordinateToResizedSymbolTransformMat = compose8(
23431
- translate9(globalPos.x, globalPos.y),
23466
+ this.userCoordinateToResizedSymbolTransformMat = compose9(
23467
+ translate10(globalPos.x, globalPos.y),
23432
23468
  scale2(scaleX, scaleY),
23433
- translate9(-currentCenterX, -currentCenterY)
23469
+ translate10(-currentCenterX, -currentCenterY)
23434
23470
  );
23435
23471
  }
23436
23472
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1073",
4
+ "version": "0.0.1074",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -35,7 +35,7 @@
35
35
  "@tscircuit/alphabet": "0.0.18",
36
36
  "@tscircuit/capacity-autorouter": "^0.0.299",
37
37
  "@tscircuit/checks": "0.0.100",
38
- "@tscircuit/circuit-json-util": "^0.0.80",
38
+ "@tscircuit/circuit-json-util": "^0.0.81",
39
39
  "@tscircuit/common": "^0.0.20",
40
40
  "@tscircuit/copper-pour-solver": "^0.0.20",
41
41
  "@tscircuit/footprinter": "^0.0.316",