@tscircuit/core 0.0.3 → 0.0.5
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.cjs +783 -4808
- package/lib/components/index.ts +1 -0
- package/lib/components/normal-components/Chip.ts +113 -0
- package/lib/components/primitive-components/Port.ts +4 -0
- package/lib/soup/underscorifyPinStyles.ts +23 -0
- package/lib/soup/underscorifyPortArrangement.ts +51 -0
- package/lib/utils/range.ts +8 -0
- package/lib/utils/schematic/getAllDimensionsForSchematicBox.ts +330 -0
- package/lib/utils/schematic/getSizeOfSidesFromPortArrangement.ts +47 -0
- package/lib/utils/selector-matching/index.ts +1 -1
- package/package.json +6 -5
package/lib/components/index.ts
CHANGED
|
@@ -12,3 +12,4 @@ export { Net } from "./primitive-components/Net"
|
|
|
12
12
|
export { Trace } from "./primitive-components/Trace"
|
|
13
13
|
export { TraceHint } from "./primitive-components/TraceHint"
|
|
14
14
|
export { Group } from "./primitive-components/Group"
|
|
15
|
+
export { Chip } from "./normal-components/Chip"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { NormalComponent } from "lib/components/base-components/NormalComponent"
|
|
2
|
+
import { chipProps } from "@tscircuit/props"
|
|
3
|
+
import { Port } from "../primitive-components/Port"
|
|
4
|
+
import type { BaseSymbolName } from "lib/utils/constants"
|
|
5
|
+
import {
|
|
6
|
+
getAllDimensionsForSchematicBox,
|
|
7
|
+
type SchematicBoxDimensions,
|
|
8
|
+
} from "lib/utils/schematic/getAllDimensionsForSchematicBox"
|
|
9
|
+
import { underscorifyPortArrangement } from "lib/soup/underscorifyPortArrangement"
|
|
10
|
+
import { underscorifyPinStyles } from "lib/soup/underscorifyPinStyles"
|
|
11
|
+
|
|
12
|
+
export class Chip<PinLabels extends string = never> extends NormalComponent<
|
|
13
|
+
typeof chipProps,
|
|
14
|
+
PinLabels
|
|
15
|
+
> {
|
|
16
|
+
schematicDimensions: SchematicBoxDimensions | null = null
|
|
17
|
+
|
|
18
|
+
get config() {
|
|
19
|
+
return {
|
|
20
|
+
zodProps: chipProps,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
initPorts() {
|
|
25
|
+
super.initPorts()
|
|
26
|
+
|
|
27
|
+
const { _parsedProps: props } = this
|
|
28
|
+
|
|
29
|
+
if (props.pinLabels) {
|
|
30
|
+
for (const [pinNumber, label] of Object.entries(props.pinLabels)) {
|
|
31
|
+
const port = this.selectOne(`port[pinNumber='${pinNumber}']`)
|
|
32
|
+
if (!port) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Could not find port for pin number ${pinNumber} in chip ${this.getString()}`,
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
port.props.aliases.push(port.props.name)
|
|
38
|
+
port.props.name = label
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
doInitialSourceRender(): void {
|
|
44
|
+
const { db } = this.project!
|
|
45
|
+
const { _parsedProps: props } = this
|
|
46
|
+
|
|
47
|
+
const source_component = db.source_component.insert({
|
|
48
|
+
ftype: "simple_chip",
|
|
49
|
+
name: props.name,
|
|
50
|
+
manufacturer_part_number: props.manufacturerPartNumber,
|
|
51
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
this.source_component_id = source_component.source_component_id!
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
doInitialSchematicComponentRender() {
|
|
58
|
+
const { db } = this.project!
|
|
59
|
+
const { _parsedProps: props } = this
|
|
60
|
+
|
|
61
|
+
const pinSpacing = props.schPinSpacing ?? 0.2
|
|
62
|
+
|
|
63
|
+
const dimensions = getAllDimensionsForSchematicBox({
|
|
64
|
+
schWidth: props.schWidth,
|
|
65
|
+
schHeight: props.schHeight,
|
|
66
|
+
schPinSpacing: pinSpacing,
|
|
67
|
+
schPinStyle: props.schPinStyle,
|
|
68
|
+
|
|
69
|
+
// @ts-ignore there's a subtley in the definition difference with
|
|
70
|
+
// leftSide/rightSide/topSide/bottomSide in how the direction is defined
|
|
71
|
+
// that doesn't really matter
|
|
72
|
+
schPortArrangement: props.schPortArrangement,
|
|
73
|
+
})
|
|
74
|
+
this.schematicDimensions = dimensions
|
|
75
|
+
|
|
76
|
+
const schematic_component = db.schematic_component.insert({
|
|
77
|
+
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
78
|
+
rotation: props.schRotation ?? 0,
|
|
79
|
+
size: dimensions.getSize(),
|
|
80
|
+
|
|
81
|
+
port_arrangement: underscorifyPortArrangement(
|
|
82
|
+
props.schPortArrangement as any,
|
|
83
|
+
),
|
|
84
|
+
|
|
85
|
+
pin_spacing: pinSpacing,
|
|
86
|
+
|
|
87
|
+
// @ts-ignore soup needs to support distance for pin_styles
|
|
88
|
+
pin_styles: underscorifyPinStyles(props.schPinStyle),
|
|
89
|
+
|
|
90
|
+
port_labels: props.pinLabels,
|
|
91
|
+
|
|
92
|
+
source_component_id: this.source_component_id!,
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
this.schematic_component_id = schematic_component.schematic_component_id
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
doInitialPcbComponentRender() {
|
|
99
|
+
const { db } = this.project!
|
|
100
|
+
const { _parsedProps: props } = this
|
|
101
|
+
|
|
102
|
+
const pcb_component = db.pcb_component.insert({
|
|
103
|
+
center: { x: props.pcbX ?? 0, y: props.pcbY ?? 0 },
|
|
104
|
+
width: 2, // Default width, adjust as needed
|
|
105
|
+
height: 3, // Default height, adjust as needed
|
|
106
|
+
layer: props.layer ?? "top",
|
|
107
|
+
rotation: props.pcbRotation ?? 0,
|
|
108
|
+
source_component_id: this.source_component_id!,
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
this.pcb_component_id = pcb_component.pcb_component_id
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -45,6 +45,10 @@ export class Port extends PrimitiveComponent<typeof portProps> {
|
|
|
45
45
|
|
|
46
46
|
getGlobalSchematicPosition(): { x: number; y: number } {
|
|
47
47
|
if (!this.schematicSymbolPortDef) {
|
|
48
|
+
return applyToPoint(this.parent!.computeSchematicGlobalTransform(), {
|
|
49
|
+
x: 0,
|
|
50
|
+
y: 0,
|
|
51
|
+
})
|
|
48
52
|
throw new Error(
|
|
49
53
|
`Could not find schematic symbol port for port ${this} so couldn't determine port position`,
|
|
50
54
|
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SchematicPinStyles } from "@tscircuit/props"
|
|
2
|
+
import { schematic_component } from "@tscircuit/soup"
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
|
|
5
|
+
type UnderscorePinStyles = z.input<typeof schematic_component>["pin_styles"]
|
|
6
|
+
|
|
7
|
+
export const underscorifyPinStyles = (
|
|
8
|
+
pinStyles: SchematicPinStyles | undefined,
|
|
9
|
+
): UnderscorePinStyles | undefined => {
|
|
10
|
+
if (!pinStyles) return undefined
|
|
11
|
+
const underscorePinStyles: UnderscorePinStyles = {}
|
|
12
|
+
|
|
13
|
+
for (const [pinName, pinStyle] of Object.entries(pinStyles)) {
|
|
14
|
+
underscorePinStyles[pinName] = {
|
|
15
|
+
bottom_margin: pinStyle.bottomMargin,
|
|
16
|
+
left_margin: pinStyle.leftMargin,
|
|
17
|
+
right_margin: pinStyle.rightMargin,
|
|
18
|
+
top_margin: pinStyle.topMargin,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return underscorePinStyles
|
|
23
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { SchematicComponentInput } from "@tscircuit/soup"
|
|
2
|
+
import type { PortArrangement } from "lib/utils/schematic/getAllDimensionsForSchematicBox"
|
|
3
|
+
|
|
4
|
+
export const underscorifyPortArrangement = (
|
|
5
|
+
portArrangement?: PortArrangement | undefined,
|
|
6
|
+
): SchematicComponentInput["port_arrangement"] | undefined => {
|
|
7
|
+
if (!portArrangement) return undefined
|
|
8
|
+
if (
|
|
9
|
+
"leftSide" in portArrangement ||
|
|
10
|
+
"rightSide" in portArrangement ||
|
|
11
|
+
"topSide" in portArrangement ||
|
|
12
|
+
"bottomSide" in portArrangement
|
|
13
|
+
) {
|
|
14
|
+
return {
|
|
15
|
+
left_side: portArrangement.leftSide,
|
|
16
|
+
right_side: portArrangement.rightSide,
|
|
17
|
+
top_side: portArrangement.topSide,
|
|
18
|
+
bottom_side: portArrangement.bottomSide,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (
|
|
23
|
+
"leftPinCount" in portArrangement ||
|
|
24
|
+
"rightPinCount" in portArrangement ||
|
|
25
|
+
"topPinCount" in portArrangement ||
|
|
26
|
+
"bottomPinCount" in portArrangement
|
|
27
|
+
) {
|
|
28
|
+
return {
|
|
29
|
+
left_size: portArrangement.leftPinCount!,
|
|
30
|
+
right_size: portArrangement.rightPinCount!,
|
|
31
|
+
top_size: portArrangement.topPinCount,
|
|
32
|
+
bottom_size: portArrangement.bottomPinCount,
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (
|
|
37
|
+
"leftSize" in portArrangement ||
|
|
38
|
+
"rightSize" in portArrangement ||
|
|
39
|
+
"topSize" in portArrangement ||
|
|
40
|
+
"bottomSize" in portArrangement
|
|
41
|
+
) {
|
|
42
|
+
return {
|
|
43
|
+
left_size: portArrangement.leftSize!,
|
|
44
|
+
right_size: portArrangement.rightSize!,
|
|
45
|
+
top_size: portArrangement.topSize,
|
|
46
|
+
bottom_size: portArrangement.bottomSize,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return undefined
|
|
51
|
+
}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { current } from "@tscircuit/soup"
|
|
2
|
+
import { getSizeOfSidesFromPortArrangement } from "./getSizeOfSidesFromPortArrangement"
|
|
3
|
+
import { schematicPortArrangement } from "@tscircuit/props"
|
|
4
|
+
import { z } from "zod"
|
|
5
|
+
|
|
6
|
+
export type VerticalPortSideConfiguration = {
|
|
7
|
+
direction?: "top-to-bottom" | "bottom-to-top"
|
|
8
|
+
pins: number[]
|
|
9
|
+
}
|
|
10
|
+
export type HorizontalPortSideConfiguration = {
|
|
11
|
+
direction?: "left-to-right" | "right-to-left"
|
|
12
|
+
pins: number[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type ExplicitPinMappingArrangement = {
|
|
16
|
+
leftSide?: VerticalPortSideConfiguration
|
|
17
|
+
rightSide?: VerticalPortSideConfiguration
|
|
18
|
+
topSide?: HorizontalPortSideConfiguration
|
|
19
|
+
bottomSide?: HorizontalPortSideConfiguration
|
|
20
|
+
}
|
|
21
|
+
/** @deprecated prefer SidePinCounts */
|
|
22
|
+
export interface SideSizes {
|
|
23
|
+
leftSize?: number
|
|
24
|
+
rightSize?: number
|
|
25
|
+
topSize?: number
|
|
26
|
+
bottomSize?: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface SidePinCounts {
|
|
30
|
+
leftPinCount?: number
|
|
31
|
+
rightPinCount?: number
|
|
32
|
+
topPinCount?: number
|
|
33
|
+
bottomPinCount?: number
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type PortArrangement =
|
|
37
|
+
| SideSizes
|
|
38
|
+
| SidePinCounts
|
|
39
|
+
| ExplicitPinMappingArrangement
|
|
40
|
+
|
|
41
|
+
interface Params {
|
|
42
|
+
schWidth?: number
|
|
43
|
+
schHeight?: number
|
|
44
|
+
portDistanceFromEdge?: number
|
|
45
|
+
schPinSpacing: number
|
|
46
|
+
schPinStyle?: Record<
|
|
47
|
+
`pin${number}` | number | `${number}`,
|
|
48
|
+
{
|
|
49
|
+
leftMargin?: number
|
|
50
|
+
rightMargin?: number
|
|
51
|
+
topMargin?: number
|
|
52
|
+
bottomMargin?: number
|
|
53
|
+
}
|
|
54
|
+
>
|
|
55
|
+
pinCount?: number
|
|
56
|
+
schPortArrangement?: PortArrangement
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type Side = "left" | "right" | "top" | "bottom"
|
|
60
|
+
|
|
61
|
+
export interface SchematicBoxDimensions {
|
|
62
|
+
pinCount: number
|
|
63
|
+
getPortPositionByPinNumber(pinNumber: number): { x: number; y: number }
|
|
64
|
+
getSize(): { width: number; height: number }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get the dimensions of a schematic box based on the provided parameters.
|
|
69
|
+
*
|
|
70
|
+
* A schematic box is a rectangular box with a set of pins on the sides.
|
|
71
|
+
*
|
|
72
|
+
* The user can customize the position of the pins and the spacing between them,
|
|
73
|
+
* this makes computing the box fairly complicated.
|
|
74
|
+
*
|
|
75
|
+
* A note on the internals:
|
|
76
|
+
* * A "true port" refers to a pin/port before it's remapped by the user to a
|
|
77
|
+
* different position. True Pin 1 is guaranteed to be in the top-left corner
|
|
78
|
+
* * We basically iterate over each side and compute how far we are from the
|
|
79
|
+
* edge for that side by adding margins together
|
|
80
|
+
*/
|
|
81
|
+
export const getAllDimensionsForSchematicBox = (
|
|
82
|
+
params: Params,
|
|
83
|
+
): SchematicBoxDimensions => {
|
|
84
|
+
const portDistanceFromEdge =
|
|
85
|
+
params.portDistanceFromEdge ?? params.schPinSpacing * 2
|
|
86
|
+
|
|
87
|
+
let sidePinCounts = params.schPortArrangement
|
|
88
|
+
? getSizeOfSidesFromPortArrangement(params.schPortArrangement)
|
|
89
|
+
: null
|
|
90
|
+
|
|
91
|
+
const sideLengths: Record<Side, number> = {
|
|
92
|
+
left: 0,
|
|
93
|
+
right: 0,
|
|
94
|
+
top: 0,
|
|
95
|
+
bottom: 0,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let pinCount: number | null = params.pinCount ?? null
|
|
99
|
+
|
|
100
|
+
if (pinCount === null) {
|
|
101
|
+
if (sidePinCounts) {
|
|
102
|
+
pinCount =
|
|
103
|
+
sidePinCounts.leftSize + sidePinCounts.rightSize + sidePinCounts.topSize
|
|
104
|
+
} else {
|
|
105
|
+
throw new Error("Could not determine pin count for the schematic box")
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (pinCount && !sidePinCounts) {
|
|
110
|
+
const rightSize = Math.floor(pinCount / 2)
|
|
111
|
+
sidePinCounts = {
|
|
112
|
+
leftSize: pinCount - rightSize,
|
|
113
|
+
rightSize: rightSize,
|
|
114
|
+
topSize: 0,
|
|
115
|
+
bottomSize: 0,
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!sidePinCounts) {
|
|
120
|
+
throw new Error("Could not determine side sizes for the schematic box")
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Map the indices to the sides they correspond to
|
|
124
|
+
const orderedTruePorts: Array<{
|
|
125
|
+
trueIndex: number
|
|
126
|
+
pinNumber: number
|
|
127
|
+
side: "left" | "right" | "top" | "bottom"
|
|
128
|
+
distanceFromEdge: number
|
|
129
|
+
}> = []
|
|
130
|
+
let currentDistanceFromEdge = 0
|
|
131
|
+
let truePinIndex = 0
|
|
132
|
+
// moving downward from the top-left corner
|
|
133
|
+
for (let sideIndex = 0; sideIndex < sidePinCounts.leftSize; sideIndex++) {
|
|
134
|
+
const pinNumber = truePinIndex + 1 // TODO check mapping from schPortArrangement
|
|
135
|
+
const pinStyle =
|
|
136
|
+
params.schPinStyle?.[`pin${pinNumber}`] ?? params.schPinStyle?.[pinNumber]
|
|
137
|
+
|
|
138
|
+
if (pinStyle?.topMargin) {
|
|
139
|
+
currentDistanceFromEdge += pinStyle.topMargin
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
orderedTruePorts.push({
|
|
143
|
+
trueIndex: truePinIndex,
|
|
144
|
+
pinNumber,
|
|
145
|
+
side: "left",
|
|
146
|
+
distanceFromEdge: currentDistanceFromEdge,
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
if (pinStyle?.bottomMargin) {
|
|
150
|
+
currentDistanceFromEdge += pinStyle.bottomMargin
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const isLastPinOnSide = sideIndex === sidePinCounts.leftSize - 1
|
|
154
|
+
if (!isLastPinOnSide) {
|
|
155
|
+
currentDistanceFromEdge += params.schPinSpacing
|
|
156
|
+
} else {
|
|
157
|
+
sideLengths.left = currentDistanceFromEdge
|
|
158
|
+
}
|
|
159
|
+
truePinIndex++
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
currentDistanceFromEdge = 0
|
|
163
|
+
// moving rightward from the left-bottom corner
|
|
164
|
+
for (let sideIndex = 0; sideIndex < sidePinCounts.bottomSize; sideIndex++) {
|
|
165
|
+
const pinNumber = truePinIndex + 1 // TODO check mapping from schPortArrangement
|
|
166
|
+
const pinStyle =
|
|
167
|
+
params.schPinStyle?.[`pin${pinNumber}`] ?? params.schPinStyle?.[pinNumber]
|
|
168
|
+
|
|
169
|
+
if (pinStyle?.leftMargin) {
|
|
170
|
+
currentDistanceFromEdge += pinStyle.leftMargin
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
orderedTruePorts.push({
|
|
174
|
+
trueIndex: truePinIndex,
|
|
175
|
+
pinNumber,
|
|
176
|
+
side: "bottom",
|
|
177
|
+
distanceFromEdge: currentDistanceFromEdge,
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
if (pinStyle?.rightMargin) {
|
|
181
|
+
currentDistanceFromEdge += pinStyle.rightMargin
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const isLastPinOnSide = sideIndex === sidePinCounts.bottomSize - 1
|
|
185
|
+
if (!isLastPinOnSide) {
|
|
186
|
+
currentDistanceFromEdge += params.schPinSpacing
|
|
187
|
+
} else {
|
|
188
|
+
sideLengths.bottom = currentDistanceFromEdge
|
|
189
|
+
}
|
|
190
|
+
truePinIndex++
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
currentDistanceFromEdge = 0
|
|
194
|
+
// moving upward from the bottom-right corner
|
|
195
|
+
for (let sideIndex = 0; sideIndex < sidePinCounts.rightSize; sideIndex++) {
|
|
196
|
+
const pinNumber = truePinIndex + 1 // TODO check mapping from schPortArrangement
|
|
197
|
+
const pinStyle =
|
|
198
|
+
params.schPinStyle?.[`pin${pinNumber}`] ?? params.schPinStyle?.[pinNumber]
|
|
199
|
+
|
|
200
|
+
if (pinStyle?.bottomMargin) {
|
|
201
|
+
currentDistanceFromEdge += pinStyle.bottomMargin
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
orderedTruePorts.push({
|
|
205
|
+
trueIndex: truePinIndex,
|
|
206
|
+
pinNumber,
|
|
207
|
+
side: "right",
|
|
208
|
+
distanceFromEdge: currentDistanceFromEdge,
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
if (pinStyle?.topMargin) {
|
|
212
|
+
currentDistanceFromEdge += pinStyle.topMargin
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const isLastPinOnSide = sideIndex === sidePinCounts.rightSize - 1
|
|
216
|
+
if (!isLastPinOnSide) {
|
|
217
|
+
currentDistanceFromEdge += params.schPinSpacing
|
|
218
|
+
} else {
|
|
219
|
+
sideLengths.right = currentDistanceFromEdge
|
|
220
|
+
}
|
|
221
|
+
truePinIndex++
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
currentDistanceFromEdge = 0
|
|
225
|
+
// moving leftward from the top-right corner
|
|
226
|
+
for (let sideIndex = 0; sideIndex < sidePinCounts.topSize; sideIndex++) {
|
|
227
|
+
const pinNumber = truePinIndex + 1 // TODO check mapping from schPortArrangement
|
|
228
|
+
const pinStyle =
|
|
229
|
+
params.schPinStyle?.[`pin${pinNumber}`] ?? params.schPinStyle?.[pinNumber]
|
|
230
|
+
|
|
231
|
+
if (pinStyle?.rightMargin) {
|
|
232
|
+
currentDistanceFromEdge += pinStyle.rightMargin
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
orderedTruePorts.push({
|
|
236
|
+
trueIndex: truePinIndex,
|
|
237
|
+
pinNumber,
|
|
238
|
+
side: "top",
|
|
239
|
+
distanceFromEdge: currentDistanceFromEdge,
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
if (pinStyle?.leftMargin) {
|
|
243
|
+
currentDistanceFromEdge += pinStyle.leftMargin
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const isLastPinOnSide = sideIndex === sidePinCounts.topSize - 1
|
|
247
|
+
if (!isLastPinOnSide) {
|
|
248
|
+
currentDistanceFromEdge += params.schPinSpacing
|
|
249
|
+
} else {
|
|
250
|
+
sideLengths.top = currentDistanceFromEdge
|
|
251
|
+
}
|
|
252
|
+
truePinIndex++
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Use lengths to determine schWidth and schHeight
|
|
256
|
+
let schWidth = params.schWidth
|
|
257
|
+
if (!schWidth) {
|
|
258
|
+
schWidth = Math.max(
|
|
259
|
+
sideLengths.top + params.schPinSpacing * 2,
|
|
260
|
+
sideLengths.bottom + params.schPinSpacing * 2,
|
|
261
|
+
)
|
|
262
|
+
}
|
|
263
|
+
let schHeight = params.schHeight
|
|
264
|
+
if (!schHeight) {
|
|
265
|
+
schHeight = Math.max(
|
|
266
|
+
sideLengths.left + params.schPinSpacing * 2,
|
|
267
|
+
sideLengths.right + params.schPinSpacing * 2,
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const trueEdgePositions = {
|
|
272
|
+
// Top left corner
|
|
273
|
+
left: {
|
|
274
|
+
x: -schWidth / 2 - portDistanceFromEdge,
|
|
275
|
+
y: sideLengths.left / 2,
|
|
276
|
+
},
|
|
277
|
+
// bottom left corner
|
|
278
|
+
bottom: {
|
|
279
|
+
x: -sideLengths.bottom / 2,
|
|
280
|
+
y: -schHeight / 2 - portDistanceFromEdge,
|
|
281
|
+
},
|
|
282
|
+
// bottom right corner
|
|
283
|
+
right: {
|
|
284
|
+
x: schWidth / 2 + portDistanceFromEdge,
|
|
285
|
+
y: -sideLengths.right / 2,
|
|
286
|
+
},
|
|
287
|
+
// top right corner
|
|
288
|
+
top: {
|
|
289
|
+
x: sideLengths.top / 2,
|
|
290
|
+
y: schHeight / 2 + portDistanceFromEdge,
|
|
291
|
+
},
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const trueEdgeTraversalDirections = {
|
|
295
|
+
left: { x: 0, y: -1 },
|
|
296
|
+
right: { x: 0, y: 1 },
|
|
297
|
+
top: { x: -1, y: 0 },
|
|
298
|
+
bottom: { x: 1, y: 0 },
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const truePortsWithPositions = orderedTruePorts.map((p) => {
|
|
302
|
+
const { distanceFromEdge, side } = p
|
|
303
|
+
const edgePos = trueEdgePositions[side]
|
|
304
|
+
const edgeDir = trueEdgeTraversalDirections[side]
|
|
305
|
+
|
|
306
|
+
return {
|
|
307
|
+
x: edgePos.x + distanceFromEdge * edgeDir.x,
|
|
308
|
+
y: edgePos.y + distanceFromEdge * edgeDir.y,
|
|
309
|
+
...p,
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
getPortPositionByPinNumber(pinNumber: number): { x: number; y: number } {
|
|
315
|
+
const port = truePortsWithPositions.find(
|
|
316
|
+
(p) => p.pinNumber.toString() === pinNumber.toString(),
|
|
317
|
+
)
|
|
318
|
+
if (!port) {
|
|
319
|
+
throw new Error(
|
|
320
|
+
`Could not find port for pin number ${pinNumber}, available pins: ${truePortsWithPositions.map((tp) => tp.pinNumber).join(", ")}`,
|
|
321
|
+
)
|
|
322
|
+
}
|
|
323
|
+
return port
|
|
324
|
+
},
|
|
325
|
+
getSize(): { width: number; height: number } {
|
|
326
|
+
return { width: schWidth, height: schHeight }
|
|
327
|
+
},
|
|
328
|
+
pinCount,
|
|
329
|
+
}
|
|
330
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ExplicitPinMappingArrangement,
|
|
3
|
+
PortArrangement,
|
|
4
|
+
} from "./getAllDimensionsForSchematicBox"
|
|
5
|
+
|
|
6
|
+
export const hasExplicitPinMapping = (
|
|
7
|
+
pa: PortArrangement,
|
|
8
|
+
): pa is ExplicitPinMappingArrangement => {
|
|
9
|
+
for (const side of [
|
|
10
|
+
"leftSide",
|
|
11
|
+
"rightSide",
|
|
12
|
+
"topSide",
|
|
13
|
+
"bottomSide",
|
|
14
|
+
] as const) {
|
|
15
|
+
if (side in pa && typeof (pa as any)[side] === "number") {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`A number was specified for "${side}", you probably meant to use "size" not "side"`,
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return (
|
|
22
|
+
"leftSide" in pa ||
|
|
23
|
+
"rightSide" in pa ||
|
|
24
|
+
"topSide" in pa ||
|
|
25
|
+
"bottomSide" in pa
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const getSizeOfSidesFromPortArrangement = (
|
|
30
|
+
pa: PortArrangement,
|
|
31
|
+
): {
|
|
32
|
+
leftSize: number
|
|
33
|
+
rightSize: number
|
|
34
|
+
topSize: number
|
|
35
|
+
bottomSize: number
|
|
36
|
+
} => {
|
|
37
|
+
if (hasExplicitPinMapping(pa)) {
|
|
38
|
+
return {
|
|
39
|
+
leftSize: pa.leftSide?.pins.length ?? 0,
|
|
40
|
+
rightSize: pa.rightSide?.pins.length ?? 0,
|
|
41
|
+
topSize: pa.topSide?.pins.length ?? 0,
|
|
42
|
+
bottomSize: pa.bottomSide?.pins.length ?? 0,
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const { leftSize = 0, rightSize = 0, topSize = 0, bottomSize = 0 } = pa as any
|
|
46
|
+
return { leftSize, rightSize, topSize, bottomSize }
|
|
47
|
+
}
|
|
@@ -57,6 +57,6 @@ export function isMatchingSelector(
|
|
|
57
57
|
const match = condition.match(/\[(\w+)=['"]?(.+?)['"]?\]/)
|
|
58
58
|
if (!match) return true
|
|
59
59
|
const [, prop, value] = match
|
|
60
|
-
return component.props[prop] === value
|
|
60
|
+
return component.props[prop].toString() === value
|
|
61
61
|
})
|
|
62
62
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"module": "index.ts",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "index.ts",
|
|
6
|
-
"version": "0.0.
|
|
6
|
+
"version": "0.0.5",
|
|
7
7
|
"main": "dist/index.cjs",
|
|
8
8
|
"files": [
|
|
9
9
|
"index.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"dist"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "tsup index.ts"
|
|
14
|
+
"build": "tsup-node index.ts"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"@biomejs/biome": "^1.8.3",
|
|
@@ -28,13 +28,14 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@tscircuit/infgrid-ijump-astar": "0.0.4",
|
|
31
|
-
"@tscircuit/props": "^0.0.
|
|
32
|
-
"@tscircuit/soup": "^0.0.
|
|
31
|
+
"@tscircuit/props": "^0.0.46",
|
|
32
|
+
"@tscircuit/soup": "^0.0.58",
|
|
33
33
|
"@tscircuit/soup-util": "0.0.18",
|
|
34
34
|
"footprinter": "^0.0.44",
|
|
35
35
|
"react": "^18.3.1",
|
|
36
36
|
"react-reconciler": "^0.29.2",
|
|
37
37
|
"schematic-symbols": "0.0.10",
|
|
38
|
-
"transformation-matrix": "^2.16.1"
|
|
38
|
+
"transformation-matrix": "^2.16.1",
|
|
39
|
+
"zod": "^3.23.8"
|
|
39
40
|
}
|
|
40
41
|
}
|