diff --git a/bun.lock b/bun.lock
index 50bf881..6f72f97 100644
--- a/bun.lock
+++ b/bun.lock
@@ -6,7 +6,7 @@
"name": "jscad-electronics",
"devDependencies": {
"@biomejs/biome": "^1.9.3",
- "@tscircuit/footprinter": "^0.0.374",
+ "@tscircuit/footprinter": "^0.0.391",
"@types/react": "19",
"@types/react-dom": "19",
"@types/three": "^0.179.0",
@@ -179,7 +179,7 @@
"@tscircuit/alphabet": ["@tscircuit/alphabet@0.0.24", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-vYYLwDwpTULFDwuqB5+U4RlTiHJ3Ez4Sf5OEv7rB1oVbhmh8p3Xl7h3vsi5eD4SE+x+0e8eSXKSlwSLCN94vZA=="],
- "@tscircuit/footprinter": ["@tscircuit/footprinter@0.0.374", "", { "dependencies": { "@tscircuit/mm": "^0.0.8", "zod": "^3.23.8" }, "peerDependencies": { "circuit-json": "*" } }, "sha512-TqcB8fBoquEWCOIttNSvq3OD+g3j9INFn0Zn//Jmje8U42TW7SpxW5vF+N04zoCmIQ3WkMpeC2032zD4uYbg5Q=="],
+ "@tscircuit/footprinter": ["@tscircuit/footprinter@0.0.391", "", { "dependencies": { "@tscircuit/mm": "^0.0.8", "zod": "^3.23.8" }, "peerDependencies": { "circuit-json": "*" } }, "sha512-6sUm5uyUJjk0U19Fy1J6w5lfxdB1kQe8lMTtWjjnSTP2dCKmcoBS1Hy5bWhvRuWllYwZkAwztsHYI9DnYDoj6w=="],
"@tscircuit/mm": ["@tscircuit/mm@0.0.8", "", { "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-nl7nxE7AhARbKuobflI0LUzoir7+wJyvwfPw6bzA/O0Q3YTcH3vBkU/Of+V/fp6ht+AofiCXj7YAH9E446138Q=="],
diff --git a/examples/footprinter3d/fp-usbcmidmount16.example.tsx b/examples/footprinter3d/fp-usbcmidmount16.example.tsx
new file mode 100644
index 0000000..5ecb776
--- /dev/null
+++ b/examples/footprinter3d/fp-usbcmidmount16.example.tsx
@@ -0,0 +1,12 @@
+import { JsCadView } from "jscad-fiber"
+import { ExtrudedPads } from "lib/ExtrudedPads"
+import { Footprinter3d } from "lib/Footprinter3d"
+
+const footprint = "usbcmidmount16"
+
+export default () => (
+
+
+
+
+)
diff --git a/lib/Footprinter3d.tsx b/lib/Footprinter3d.tsx
index a32c152..9ca876f 100644
--- a/lib/Footprinter3d.tsx
+++ b/lib/Footprinter3d.tsx
@@ -57,6 +57,7 @@ import { StampBoard } from "./stampboard"
import { MountedPcbModule } from "./MountedPcbModule"
import SOD723 from "./SOD723"
import { JSTZH1_5mm } from "./JSTZH1_5mm"
+import { UsbCMidMount } from "./UsbCMidMount"
/**
* Outputs a 3d model for any [footprinter string](https://github.com/tscircuit/footprinter)
@@ -103,6 +104,22 @@ export const Footprinter3d = ({ footprint }: { footprint: string }) => {
screenheight?: number
screencenteroffsetx?: number
screencenteroffsety?: number
+ split?: boolean
+ reverse?: boolean
+ rowy?: number
+ ph?: number
+ powerpw?: number
+ powerx?: number
+ shellx?: number
+ topy?: number
+ bottomy?: number
+ tophw?: number
+ tophh?: number
+ topring?: number
+ bottomhw?: number
+ bottomhh?: number
+ bottomring?: number
+ bodybottom?: number
}
switch (fpJson.fn) {
@@ -287,6 +304,28 @@ export const Footprinter3d = ({ footprint }: { footprint: string }) => {
return
}
break
+ case "usbcmidmount":
+ return (
+
+ )
case "soic":
return (
{
+ const innerPowerX = powerX - 0.8
+ const mergedSignalXs = [
+ -powerX,
+ -innerPowerX,
+ -1.75,
+ -1.25,
+ -0.75,
+ -0.25,
+ 0.25,
+ 0.75,
+ 1.25,
+ 1.75,
+ innerPowerX,
+ powerX,
+ ]
+ const splitSignalXs = [
+ -3.35, -3.05, -2.55, -2.25, -1.75, -1.25, -0.75, -0.25, 0.25, 0.75, 1.25,
+ 1.75, 2.25, 2.55, 3.05, 3.35,
+ ]
+ const leftToRightSignalXs = split ? splitSignalXs : mergedSignalXs
+ const signalXs = reverse
+ ? leftToRightSignalXs.slice().reverse()
+ : leftToRightSignalXs.slice()
+ const signalWidths = signalXs.map((_, index) =>
+ split || (index >= 2 && index < signalXs.length - 2)
+ ? signalPadWidth
+ : powerPadWidth,
+ )
+ const rearY = rowY + padHeight / 2
+ const frontY = -bodyBottom
+ const bodyDepth = rearY - frontY
+ const bodyCenterY = (rearY + frontY) / 2
+ const outerWidth = shellX * 2 - 0.1
+ const outerHeight = 2.5
+ const bodyCenterZ = 0.25
+ const innerWidth = Math.max(outerWidth - 0.85, 5)
+ const innerHeight = outerHeight - 0.65
+ const shellThickness = 0.22
+ const tongueWidth = Math.min(innerWidth - 0.45, 6.6)
+ const tongueDepth = bodyDepth * 0.72
+ const tongueCenterY = frontY + tongueDepth / 2 + 0.35
+ const tongueZ = bodyCenterZ - 0.12
+ const innerContactLength = tongueDepth * 0.58
+ const innerContactY = frontY + innerContactLength / 2 + 0.55
+ const shellTabs = [
+ {
+ x: -shellX,
+ y: topY,
+ width: topHoleWidth + 2 * topRing,
+ length: topHoleHeight + 2 * topRing,
+ },
+ {
+ x: shellX,
+ y: topY,
+ width: topHoleWidth + 2 * topRing,
+ length: topHoleHeight + 2 * topRing,
+ },
+ {
+ x: -shellX,
+ y: -bottomY,
+ width: bottomHoleWidth + 2 * bottomRing,
+ length: bottomHoleHeight + 2 * bottomRing,
+ },
+ {
+ x: shellX,
+ y: -bottomY,
+ width: bottomHoleWidth + 2 * bottomRing,
+ length: bottomHoleHeight + 2 * bottomRing,
+ },
+ ]
+
+ return (
+ <>
+ {shellTabs.map((tab, index) => (
+
+ ))}
+ {signalXs.map((x, index) => (
+
+ ))}
+
+
+
+
+
+
+
+ {signalXs.map((x, index) => (
+
+ ))}
+ >
+ )
+}
diff --git a/lib/index.ts b/lib/index.ts
index c3ad613..101f0e3 100644
--- a/lib/index.ts
+++ b/lib/index.ts
@@ -70,3 +70,4 @@ export * from "./TO92"
export * from "./MountedPcbModule"
export * from "./Screen"
export * from "./JSTZH1_5mm"
+export * from "./UsbCMidMount"
diff --git a/package.json b/package.json
index 6b6f4d0..767d7c0 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,7 @@
},
"devDependencies": {
"@biomejs/biome": "^1.9.3",
- "@tscircuit/footprinter": "^0.0.374",
+ "@tscircuit/footprinter": "^0.0.391",
"@types/react": "19",
"@types/react-dom": "19",
"@types/three": "^0.179.0",
diff --git a/tests/snapshots/__snapshots__/usbcmidmount.snap.png b/tests/snapshots/__snapshots__/usbcmidmount.snap.png
new file mode 100644
index 0000000..70cb38a
Binary files /dev/null and b/tests/snapshots/__snapshots__/usbcmidmount.snap.png differ
diff --git a/tests/snapshots/usbcmidmount.test.ts b/tests/snapshots/usbcmidmount.test.ts
new file mode 100644
index 0000000..1e92c5a
--- /dev/null
+++ b/tests/snapshots/usbcmidmount.test.ts
@@ -0,0 +1,8 @@
+import { expect, test } from "bun:test"
+import "../fixtures/png-matcher"
+import { renderFootprint } from "../helpers/render-footprint"
+
+test("USB-C mid-mount connector", async () => {
+ const pngBuffer = await renderFootprint("usbcmidmount16")
+ await expect(pngBuffer).toMatchPngSnapshot(import.meta.path)
+})