Skip to content

pcbPositionMode prop typechecks but has no runtime effect — position_mode stays 'packed' #2242

@gsdali

Description

@gsdali

Summary

Setting pcbPositionMode="relative_to_board_anchor" (or any of the other PcbPositionMode enum values: "auto", "relative_to_group_anchor", "relative_to_component_anchor") on a chip/component in JSX has no observable runtime effect. The resulting pcb_component's position_mode field stays "packed" (the auto-placer's collision-avoidance mode), and the component lands wherever the placer puts it — not at the requested pcbX/pcbY.

The prop typechecks via PcbLayoutProps.pcbPositionMode in @tscircuit/props, so users assume it works. The runtime silently ignores it.

Repro

// index.circuit.tsx — board 22 × 20 mm, U1 should be at top edge
export default () => (
  <board width="22mm" height="20mm" layers={2}>
    <chip
      name="U1"
      footprint="dip8"
      pcbX={0}
      pcbY={4}
      pcbPositionMode="relative_to_board_anchor"  // ← typechecks but no-op
    />
    <resistor name="R1" resistance="1k" footprint="0402" />
  </board>
)
tsci build
jq '.[] | select(.type=="pcb_component") | {center, position_mode}' dist/index/circuit.json
# → { "center": { "x": 0, "y": 0 }, "position_mode": "packed" }
# Expected: center.y near 4, position_mode "relative_to_board_anchor"

Workaround

Add pcbX={0} pcbY={0} to the parent <group>. That presence-of-prop (regardless of value) flips the group into "relative_to_group_anchor" mode, and child pcbX/pcbY are then honoured. Discovered by JSON inspection on a real board after burning ~5 turns of debugging.

<board ...>
  <group pcbX={0} pcbY={0}>      {/* ← required */}
    <chip name="U1" pcbX={0} pcbY={4} />  {/* now lands at (0, 4) */}
  </group>
</board>

Why this matters

Component-level pcbPositionMode is the documented escape hatch for "place this exactly where I asked, ignore the auto-placer." When it silently doesn't work, there's no error, no warning — the component just shows up somewhere else. Without JSON inspection (jq against circuit.json), the failure mode is "I set pcbY=4 and the chip is at y=0 and I don't know why."

Suggested fix (any of)

  1. Implement the prop — wire it through to the placer so relative_to_board_anchor actually skips the packed-mode collision-avoidance for that component.
  2. Or warn: at JSX-prop-parse time, log a [tscircuit] pcbPositionMode is set on a component but is not yet implemented; positioning will fall back to "packed" mode unless the parent group has explicit pcbX/pcbY.
  3. Or remove from typings until implemented, so TypeScript catches the use.

Hit while placing an InsightSiP ISP3080-UX module on a daughter board — wanted U1 flush against the top edge. The pcbPositionMode prop on the chip seemed like the obvious knob; took several turns of bisection to find the group-level workaround.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions