@tscircuit/pcb-viewer 1.11.439 → 1.11.441
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.js +165 -73
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9394,6 +9394,53 @@ var getBoundsOfPcbElements = (elements) => {
|
|
|
9394
9394
|
}
|
|
9395
9395
|
return bounds;
|
|
9396
9396
|
};
|
|
9397
|
+
var getBoardBounds = (board) => {
|
|
9398
|
+
if (board.width && board.height && board.center) {
|
|
9399
|
+
const halfWidth = board.width / 2;
|
|
9400
|
+
const halfHeight = board.height / 2;
|
|
9401
|
+
return {
|
|
9402
|
+
minX: board.center.x - halfWidth,
|
|
9403
|
+
minY: board.center.y - halfHeight,
|
|
9404
|
+
maxX: board.center.x + halfWidth,
|
|
9405
|
+
maxY: board.center.y + halfHeight,
|
|
9406
|
+
width: board.width,
|
|
9407
|
+
height: board.height,
|
|
9408
|
+
center: {
|
|
9409
|
+
x: board.center.x,
|
|
9410
|
+
y: board.center.y
|
|
9411
|
+
}
|
|
9412
|
+
};
|
|
9413
|
+
}
|
|
9414
|
+
if (!board.outline || board.outline.length === 0) {
|
|
9415
|
+
throw new Error(
|
|
9416
|
+
"Unable to compute board bounds. pcb_board must include width/height/center or a non-empty outline."
|
|
9417
|
+
);
|
|
9418
|
+
}
|
|
9419
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
9420
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
9421
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
9422
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
9423
|
+
for (const point2 of board.outline) {
|
|
9424
|
+
minX = Math.min(minX, point2.x);
|
|
9425
|
+
minY = Math.min(minY, point2.y);
|
|
9426
|
+
maxX = Math.max(maxX, point2.x);
|
|
9427
|
+
maxY = Math.max(maxY, point2.y);
|
|
9428
|
+
}
|
|
9429
|
+
const width = maxX - minX;
|
|
9430
|
+
const height = maxY - minY;
|
|
9431
|
+
return {
|
|
9432
|
+
minX,
|
|
9433
|
+
minY,
|
|
9434
|
+
maxX,
|
|
9435
|
+
maxY,
|
|
9436
|
+
width,
|
|
9437
|
+
height,
|
|
9438
|
+
center: {
|
|
9439
|
+
x: minX + width / 2,
|
|
9440
|
+
y: minY + height / 2
|
|
9441
|
+
}
|
|
9442
|
+
};
|
|
9443
|
+
};
|
|
9397
9444
|
function stringHash(str) {
|
|
9398
9445
|
let hash = 0;
|
|
9399
9446
|
if (str.length == 0) return hash;
|
|
@@ -9717,6 +9764,27 @@ var getPlatedHolePolygon = (pad, componentRotation = 0) => {
|
|
|
9717
9764
|
);
|
|
9718
9765
|
};
|
|
9719
9766
|
|
|
9767
|
+
// src/lib/get-pcb-viewport-bounds.ts
|
|
9768
|
+
function getPcbViewportBounds(elements) {
|
|
9769
|
+
const pcbElements = elements.filter(
|
|
9770
|
+
(element) => element.type.startsWith("pcb_")
|
|
9771
|
+
);
|
|
9772
|
+
if (pcbElements.length === 0) {
|
|
9773
|
+
return { center: { x: 0, y: 0 }, width: 1e-3, height: 1e-3 };
|
|
9774
|
+
}
|
|
9775
|
+
const boardsAndPanels = pcbElements.filter(
|
|
9776
|
+
(element) => element.type === "pcb_board" || element.type === "pcb_panel"
|
|
9777
|
+
).map((element) => {
|
|
9778
|
+
if (element.type !== "pcb_board" || !element.outline?.length)
|
|
9779
|
+
return element;
|
|
9780
|
+
const { center, width, height } = getBoardBounds(element);
|
|
9781
|
+
return { ...element, center, width, height };
|
|
9782
|
+
});
|
|
9783
|
+
return findBoundsAndCenter(
|
|
9784
|
+
boardsAndPanels.length > 0 ? boardsAndPanels : pcbElements
|
|
9785
|
+
);
|
|
9786
|
+
}
|
|
9787
|
+
|
|
9720
9788
|
// src/lib/apply-edit-events.ts
|
|
9721
9789
|
import { translate as translate6 } from "transformation-matrix";
|
|
9722
9790
|
function applyEditEvents({
|
|
@@ -9777,13 +9845,19 @@ function applyEditEvents({
|
|
|
9777
9845
|
// src/lib/calculate-board-size-key.ts
|
|
9778
9846
|
var calculateBoardSizeKey = (circuitJson) => {
|
|
9779
9847
|
if (!circuitJson) return "empty";
|
|
9780
|
-
const
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9848
|
+
const boardSizeKeys = circuitJson.filter(
|
|
9849
|
+
(element) => element.type === "pcb_board" || element.type === "pcb_panel"
|
|
9850
|
+
).map(
|
|
9851
|
+
(element) => JSON.stringify([
|
|
9852
|
+
element.type,
|
|
9853
|
+
element.center.x,
|
|
9854
|
+
element.center.y,
|
|
9855
|
+
element.width,
|
|
9856
|
+
element.height,
|
|
9857
|
+
element.type === "pcb_board" ? element.outline?.map(({ x, y }) => [x, y]) : void 0
|
|
9858
|
+
])
|
|
9859
|
+
).sort();
|
|
9860
|
+
return boardSizeKeys.length > 0 ? boardSizeKeys.join(";") : "no-board";
|
|
9787
9861
|
};
|
|
9788
9862
|
|
|
9789
9863
|
// src/lib/calculate-circuit-json-key.ts
|
|
@@ -17373,21 +17447,33 @@ var FocusedPcbComponentOverlay = ({
|
|
|
17373
17447
|
return /* @__PURE__ */ jsx10(
|
|
17374
17448
|
"div",
|
|
17375
17449
|
{
|
|
17376
|
-
"data-
|
|
17450
|
+
"data-pcb-focus-viewport": true,
|
|
17377
17451
|
style: {
|
|
17378
17452
|
position: "absolute",
|
|
17379
|
-
|
|
17380
|
-
|
|
17381
|
-
width,
|
|
17382
|
-
height,
|
|
17383
|
-
transform: `rotate(${rotation}rad)`,
|
|
17384
|
-
transformOrigin: "center",
|
|
17385
|
-
border: "2px solid #3399ff",
|
|
17386
|
-
borderRadius: 4,
|
|
17387
|
-
boxSizing: "border-box",
|
|
17453
|
+
inset: 0,
|
|
17454
|
+
overflow: "clip",
|
|
17388
17455
|
pointerEvents: "none",
|
|
17389
17456
|
zIndex: zIndexMap.elementOverlay
|
|
17390
|
-
}
|
|
17457
|
+
},
|
|
17458
|
+
children: /* @__PURE__ */ jsx10(
|
|
17459
|
+
"div",
|
|
17460
|
+
{
|
|
17461
|
+
"data-focused-pcb-component-id": componentId,
|
|
17462
|
+
style: {
|
|
17463
|
+
position: "absolute",
|
|
17464
|
+
left: center.x - width / 2,
|
|
17465
|
+
top: center.y - height / 2,
|
|
17466
|
+
width,
|
|
17467
|
+
height,
|
|
17468
|
+
transform: `rotate(${rotation}rad)`,
|
|
17469
|
+
transformOrigin: "center",
|
|
17470
|
+
border: "2px solid #3399ff",
|
|
17471
|
+
borderRadius: 4,
|
|
17472
|
+
boxSizing: "border-box",
|
|
17473
|
+
pointerEvents: "none"
|
|
17474
|
+
}
|
|
17475
|
+
}
|
|
17476
|
+
)
|
|
17391
17477
|
}
|
|
17392
17478
|
);
|
|
17393
17479
|
};
|
|
@@ -19125,7 +19211,7 @@ import {
|
|
|
19125
19211
|
// package.json
|
|
19126
19212
|
var package_default = {
|
|
19127
19213
|
name: "@tscircuit/pcb-viewer",
|
|
19128
|
-
version: "1.11.
|
|
19214
|
+
version: "1.11.440",
|
|
19129
19215
|
main: "dist/index.js",
|
|
19130
19216
|
type: "module",
|
|
19131
19217
|
repository: {
|
|
@@ -19210,7 +19296,48 @@ var package_default = {
|
|
|
19210
19296
|
// src/components/ComponentSearch.tsx
|
|
19211
19297
|
import { css as css2 } from "@emotion/css";
|
|
19212
19298
|
import { useEffect as useEffect15, useId, useMemo as useMemo11, useRef as useRef11, useState as useState9 } from "react";
|
|
19213
|
-
|
|
19299
|
+
|
|
19300
|
+
// src/components/ToolbarButton.tsx
|
|
19301
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
19302
|
+
var getToolbarButtonStyle = (isSmallScreen) => ({
|
|
19303
|
+
backgroundColor: "#1F1F1F",
|
|
19304
|
+
border: "1px solid #666",
|
|
19305
|
+
margin: 0,
|
|
19306
|
+
padding: 4,
|
|
19307
|
+
paddingLeft: isSmallScreen ? 8 : 6,
|
|
19308
|
+
paddingRight: isSmallScreen ? 8 : 6,
|
|
19309
|
+
borderRadius: 2,
|
|
19310
|
+
color: "#eee",
|
|
19311
|
+
cursor: "pointer",
|
|
19312
|
+
fontSize: 12,
|
|
19313
|
+
height: "fit-content",
|
|
19314
|
+
userSelect: "none",
|
|
19315
|
+
whiteSpace: "nowrap"
|
|
19316
|
+
});
|
|
19317
|
+
var ToolbarButton = ({
|
|
19318
|
+
children,
|
|
19319
|
+
isSmallScreen,
|
|
19320
|
+
onClick,
|
|
19321
|
+
...props
|
|
19322
|
+
}) => {
|
|
19323
|
+
const { style: touchStyle, ...touchHandlers } = useMobileTouch(onClick);
|
|
19324
|
+
return /* @__PURE__ */ jsx20(
|
|
19325
|
+
"div",
|
|
19326
|
+
{
|
|
19327
|
+
...props,
|
|
19328
|
+
...touchHandlers,
|
|
19329
|
+
style: {
|
|
19330
|
+
...getToolbarButtonStyle(isSmallScreen),
|
|
19331
|
+
...touchStyle,
|
|
19332
|
+
...props.style
|
|
19333
|
+
},
|
|
19334
|
+
children
|
|
19335
|
+
}
|
|
19336
|
+
);
|
|
19337
|
+
};
|
|
19338
|
+
|
|
19339
|
+
// src/components/ComponentSearch.tsx
|
|
19340
|
+
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
19214
19341
|
var buttonClass = css2`
|
|
19215
19342
|
background: #1f1f1f;
|
|
19216
19343
|
border: 1px solid #666;
|
|
@@ -19225,6 +19352,7 @@ var ComponentSearch = ({
|
|
|
19225
19352
|
elements,
|
|
19226
19353
|
onSelect
|
|
19227
19354
|
}) => {
|
|
19355
|
+
const isSmallScreen = useIsSmallScreen();
|
|
19228
19356
|
const [open, setOpen] = useState9(false);
|
|
19229
19357
|
const [query, setQuery] = useState9("");
|
|
19230
19358
|
const [activeComponentId, setActiveComponentId] = useState9(
|
|
@@ -19297,7 +19425,7 @@ var ComponentSearch = ({
|
|
|
19297
19425
|
}
|
|
19298
19426
|
},
|
|
19299
19427
|
children: [
|
|
19300
|
-
/* @__PURE__ */
|
|
19428
|
+
/* @__PURE__ */ jsx21(
|
|
19301
19429
|
"button",
|
|
19302
19430
|
{
|
|
19303
19431
|
ref: toggle,
|
|
@@ -19305,15 +19433,16 @@ var ComponentSearch = ({
|
|
|
19305
19433
|
className: buttonClass,
|
|
19306
19434
|
"aria-label": "Search components",
|
|
19307
19435
|
title: "Search components",
|
|
19308
|
-
style:
|
|
19436
|
+
style: getToolbarButtonStyle(isSmallScreen),
|
|
19309
19437
|
"aria-expanded": open,
|
|
19310
19438
|
"aria-controls": panelId,
|
|
19311
19439
|
onClick: () => setOpen(!open),
|
|
19312
19440
|
children: /* @__PURE__ */ jsxs14(
|
|
19313
19441
|
"svg",
|
|
19314
19442
|
{
|
|
19315
|
-
width: "
|
|
19316
|
-
height: "
|
|
19443
|
+
width: "1em",
|
|
19444
|
+
height: "1em",
|
|
19445
|
+
style: { verticalAlign: "middle" },
|
|
19317
19446
|
viewBox: "0 0 24 24",
|
|
19318
19447
|
fill: "none",
|
|
19319
19448
|
stroke: "currentColor",
|
|
@@ -19321,8 +19450,8 @@ var ComponentSearch = ({
|
|
|
19321
19450
|
strokeLinecap: "round",
|
|
19322
19451
|
"aria-hidden": "true",
|
|
19323
19452
|
children: [
|
|
19324
|
-
/* @__PURE__ */
|
|
19325
|
-
/* @__PURE__ */
|
|
19453
|
+
/* @__PURE__ */ jsx21("circle", { cx: "10.5", cy: "10.5", r: "6.5" }),
|
|
19454
|
+
/* @__PURE__ */ jsx21("path", { d: "m16 16 5 5" })
|
|
19326
19455
|
]
|
|
19327
19456
|
}
|
|
19328
19457
|
)
|
|
@@ -19346,7 +19475,7 @@ var ComponentSearch = ({
|
|
|
19346
19475
|
boxSizing: "border-box"
|
|
19347
19476
|
},
|
|
19348
19477
|
children: [
|
|
19349
|
-
/* @__PURE__ */
|
|
19478
|
+
/* @__PURE__ */ jsx21(
|
|
19350
19479
|
"input",
|
|
19351
19480
|
{
|
|
19352
19481
|
ref: input,
|
|
@@ -19379,7 +19508,7 @@ var ComponentSearch = ({
|
|
|
19379
19508
|
}
|
|
19380
19509
|
}
|
|
19381
19510
|
),
|
|
19382
|
-
!normalizedQuery ? /* @__PURE__ */
|
|
19511
|
+
!normalizedQuery ? /* @__PURE__ */ jsx21("output", { style: { display: "block", marginTop: 8 }, children: "Type a component name." }) : matches.length === 0 ? /* @__PURE__ */ jsx21("output", { style: { display: "block", marginTop: 8 }, children: "No matching components." }) : /* @__PURE__ */ jsx21(
|
|
19383
19512
|
"div",
|
|
19384
19513
|
{
|
|
19385
19514
|
id: `${panelId}-results`,
|
|
@@ -19395,7 +19524,7 @@ var ComponentSearch = ({
|
|
|
19395
19524
|
maxHeight: 220,
|
|
19396
19525
|
overflowY: "auto"
|
|
19397
19526
|
},
|
|
19398
|
-
children: matches.map((component, index) => /* @__PURE__ */
|
|
19527
|
+
children: matches.map((component, index) => /* @__PURE__ */ jsx21("div", { role: "presentation", children: /* @__PURE__ */ jsxs14(
|
|
19399
19528
|
"button",
|
|
19400
19529
|
{
|
|
19401
19530
|
type: "button",
|
|
@@ -19417,8 +19546,8 @@ var ComponentSearch = ({
|
|
|
19417
19546
|
},
|
|
19418
19547
|
onClick: () => select(component.id),
|
|
19419
19548
|
children: [
|
|
19420
|
-
/* @__PURE__ */
|
|
19421
|
-
/* @__PURE__ */
|
|
19549
|
+
/* @__PURE__ */ jsx21("span", { children: component.name }),
|
|
19550
|
+
/* @__PURE__ */ jsx21("span", { style: { color: "#aaa" }, children: component.layer })
|
|
19422
19551
|
]
|
|
19423
19552
|
}
|
|
19424
19553
|
) }, component.id))
|
|
@@ -19432,42 +19561,6 @@ var ComponentSearch = ({
|
|
|
19432
19561
|
);
|
|
19433
19562
|
};
|
|
19434
19563
|
|
|
19435
|
-
// src/components/ToolbarButton.tsx
|
|
19436
|
-
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
19437
|
-
var ToolbarButton = ({
|
|
19438
|
-
children,
|
|
19439
|
-
isSmallScreen,
|
|
19440
|
-
onClick,
|
|
19441
|
-
...props
|
|
19442
|
-
}) => {
|
|
19443
|
-
const { style: touchStyle, ...touchHandlers } = useMobileTouch(onClick);
|
|
19444
|
-
return /* @__PURE__ */ jsx21(
|
|
19445
|
-
"div",
|
|
19446
|
-
{
|
|
19447
|
-
...props,
|
|
19448
|
-
...touchHandlers,
|
|
19449
|
-
style: {
|
|
19450
|
-
backgroundColor: "#1F1F1F",
|
|
19451
|
-
border: "1px solid #666",
|
|
19452
|
-
margin: 0,
|
|
19453
|
-
padding: 4,
|
|
19454
|
-
paddingLeft: isSmallScreen ? 8 : 6,
|
|
19455
|
-
paddingRight: isSmallScreen ? 8 : 6,
|
|
19456
|
-
borderRadius: 2,
|
|
19457
|
-
color: "#eee",
|
|
19458
|
-
cursor: "pointer",
|
|
19459
|
-
fontSize: 12,
|
|
19460
|
-
height: "fit-content",
|
|
19461
|
-
userSelect: "none",
|
|
19462
|
-
whiteSpace: "nowrap",
|
|
19463
|
-
...touchStyle,
|
|
19464
|
-
...props.style
|
|
19465
|
-
},
|
|
19466
|
-
children
|
|
19467
|
-
}
|
|
19468
|
-
);
|
|
19469
|
-
};
|
|
19470
|
-
|
|
19471
19564
|
// src/components/ToolbarErrorDropdown.tsx
|
|
19472
19565
|
import { useCallback as useCallback9, useMemo as useMemo12, useState as useState10 } from "react";
|
|
19473
19566
|
|
|
@@ -22106,14 +22199,13 @@ var PCBViewer = ({
|
|
|
22106
22199
|
() => calculateCircuitJsonKey(circuitJson),
|
|
22107
22200
|
[circuitJson]
|
|
22108
22201
|
);
|
|
22109
|
-
const boardSizeKey =
|
|
22202
|
+
const boardSizeKey = useMemo17(
|
|
22203
|
+
() => calculateBoardSizeKey(circuitJson),
|
|
22204
|
+
[circuitJson]
|
|
22205
|
+
);
|
|
22110
22206
|
const resetTransform = () => {
|
|
22111
22207
|
const elmBounds = refDimensions?.width > 0 ? refDimensions : { width: 500, height: 500 };
|
|
22112
|
-
const { center, width, height: height2 } = elements
|
|
22113
|
-
(e) => e.type.startsWith("pcb_")
|
|
22114
|
-
) ? findBoundsAndCenter(
|
|
22115
|
-
elements.filter((e) => e.type.startsWith("pcb_"))
|
|
22116
|
-
) : { center: { x: 0, y: 0 }, width: 1e-3, height: 1e-3 };
|
|
22208
|
+
const { center, width, height: height2 } = getPcbViewportBounds(elements);
|
|
22117
22209
|
const scaleFactor = Math.min(
|
|
22118
22210
|
(elmBounds.width ?? 0) / width,
|
|
22119
22211
|
(elmBounds.height ?? 0) / height2,
|