Skip to content

Commit

Permalink
Merge pull request #235 from tscircuit/pinheader
Browse files Browse the repository at this point in the history
support for pinheaders and implied footprint strings
  • Loading branch information
seveibar authored Nov 4, 2024
2 parents c5c53ee + ff80d98 commit c607334
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 2 deletions.
Binary file modified bun.lockb
Binary file not shown.
8 changes: 7 additions & 1 deletion lib/components/base-components/NormalComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export class NormalComponent<
PortNames extends string = never,
> extends PrimitiveComponent<ZodProps> {
reactSubtrees: Array<ReactSubtree> = []
_impliedFootprint?: string | undefined

isPrimitiveContainer = true

Expand Down Expand Up @@ -193,8 +194,13 @@ export class NormalComponent<
}
}

_getImpliedFootprintString(): string | null {
return null
}

_addChildrenFromStringFootprint() {
const { footprint } = this.props
let { footprint } = this.props
footprint ??= this._getImpliedFootprintString?.()
if (!footprint) return
if (typeof footprint === "string") {
const fpSoup = fp.string(footprint).soup()
Expand Down
1 change: 1 addition & 0 deletions lib/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ export { Trace } from "./primitive-components/Trace"
export { TraceHint } from "./primitive-components/TraceHint"
export { Via } from "./primitive-components/Via"
export { Battery } from "./normal-components/Battery"
export { PinHeader } from "./normal-components/PinHeader"
export { Inductor } from "./normal-components/Inductor"
77 changes: 77 additions & 0 deletions lib/components/normal-components/PinHeader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { pinHeaderProps } from "@tscircuit/props"
import { NormalComponent } from "../base-components/NormalComponent"
import { Port } from "../primitive-components/Port"
import type { BaseSymbolName } from "lib/utils/constants"

export class PinHeader extends NormalComponent<typeof pinHeaderProps> {
get config() {
return {
componentName: "PinHeader",
zodProps: pinHeaderProps,
schematicSymbolName: "pinrow_horz" as BaseSymbolName,
}
}

_getImpliedFootprintString(): string | null {
const pinCount =
this._parsedProps.pinCount ?? this._parsedProps.pinLabels?.length ?? 0
const holeDiameter = this._parsedProps.holeDiameter
const platedDiameter = this._parsedProps.platedDiameter
const pitch = this._parsedProps.pitch
if (pinCount > 0 && pitch) {
if (!holeDiameter && !platedDiameter) {
return `pinrow${pinCount}_p${pitch}`
}
return `pinrow${pinCount}_p${pitch}_id${holeDiameter}_od${platedDiameter}`
}
return null
}

initPorts() {
const pinCount =
this._parsedProps.pinCount ?? this._parsedProps.pinLabels?.length ?? 1
for (let i = 1; i <= pinCount; i++) {
this.add(
new Port({
name: `pin${i}`,
pinNumber: i,
aliases: [],
}),
)
}
}

doInitialSourceRender() {
const { db } = this.root!
const { _parsedProps: props } = this

const source_component = db.source_component.insert({
ftype: "simple_chip",
name: props.name,
// manufacturer_part_number: props.,
supplier_part_numbers: props.supplierPartNumbers,
// gender: props.gender,
// pitch: props.pitch,
})

this.source_component_id = source_component.source_component_id
}

doInitialSchematicComponentRender() {
const { db } = this.root!
const { _parsedProps: props } = this

const schematic_component = db.schematic_component.insert({
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
rotation: props.schRotation ?? 0,
size: { width: 2, height: props.pinCount ?? 1 },
source_component_id: this.source_component_id!,
port_arrangement: {
left_size: 0,
right_size: props.pinCount ?? 1,
},
})

this.schematic_component_id = schematic_component.schematic_component_id
}
}
1 change: 1 addition & 0 deletions lib/fiber/intrinsic-jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ declare global {
constraint: Props.ConstraintProps
constrainedlayout: Props.ConstrainedLayoutProps
battery: Props.BatteryProps
pinheader: Props.PinHeaderProps
jscad: any
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@tscircuit/footprinter": "^0.0.77",
"@tscircuit/infgrid-ijump-astar": "^0.0.24",
"@tscircuit/math-utils": "^0.0.4",
"@tscircuit/props": "^0.0.78",
"@tscircuit/props": "^0.0.83",
"@tscircuit/schematic-autolayout": "^0.0.5",
"@tscircuit/soup-util": "^0.0.33",
"circuit-json": "^0.0.91",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions tests/components/normal-components/header.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { test, expect } from "bun:test"
import { getTestFixture } from "tests/fixtures/get-test-fixture"

test("header with default pinrow footprint", () => {
const { project } = getTestFixture()

project.add(
<board width="10mm" height="10mm">
<pinheader name="J1" pinCount={4} pitch="2.54mm" gender="male" />
</board>,
)

project.render()

// Check if header component was created
const header = project.selectOne("pinheader")

expect(header).not.toBeNull()
expect(header!.props.name).toBe("J1")

// Check PCB primitives
const platedHoles = project.db.pcb_plated_hole.list()
expect(platedHoles).toHaveLength(4)

// Verify pin spacing
const holePositions = platedHoles.map((h) => h.x).sort((a, b) => a - b)
const spacing = holePositions[1] - holePositions[0]
expect(spacing).toBeCloseTo(2.54, 2)

expect(project).toMatchPcbSnapshot(import.meta.path)
expect(project).toMatchSchematicSnapshot(import.meta.path)
})

0 comments on commit c607334

Please sign in to comment.