@tscircuit/pcb-viewer 1.11.402 → 1.11.404
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 +145 -54
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4258,6 +4258,52 @@ var animateTransform = ({
|
|
|
4258
4258
|
import { useCallback as useCallback11, useEffect as useEffect19, useMemo as useMemo10, useRef as useRef16, useState as useState13 } from "react";
|
|
4259
4259
|
import { applyToPoint as applyToPoint19, inverse as inverse6 } from "transformation-matrix";
|
|
4260
4260
|
|
|
4261
|
+
// src/lib/get-trace-overlay-text.ts
|
|
4262
|
+
var getNonEmptyName = (name) => name?.trim() || null;
|
|
4263
|
+
function getAssociatedTraceName({
|
|
4264
|
+
primitiveElement,
|
|
4265
|
+
elements
|
|
4266
|
+
}) {
|
|
4267
|
+
const sourceElementId = primitiveElement.source_trace_id;
|
|
4268
|
+
if (!sourceElementId) return null;
|
|
4269
|
+
const circuitJson = su(elements);
|
|
4270
|
+
const sourceTrace = circuitJson.source_trace.get(sourceElementId);
|
|
4271
|
+
const sourceTraceName = getNonEmptyName(sourceTrace?.name);
|
|
4272
|
+
if (sourceTraceName) return sourceTraceName;
|
|
4273
|
+
const sourceNet = circuitJson.source_net.get(sourceElementId);
|
|
4274
|
+
const sourceNetName = getNonEmptyName(sourceNet?.name);
|
|
4275
|
+
if (sourceNetName) return sourceNetName;
|
|
4276
|
+
for (const sourceNetId of sourceTrace?.connected_source_net_ids ?? []) {
|
|
4277
|
+
const connectedSourceNetName = getNonEmptyName(
|
|
4278
|
+
circuitJson.source_net.get(sourceNetId)?.name
|
|
4279
|
+
);
|
|
4280
|
+
if (connectedSourceNetName) return connectedSourceNetName;
|
|
4281
|
+
}
|
|
4282
|
+
return null;
|
|
4283
|
+
}
|
|
4284
|
+
function getTraceOverlayInfo({
|
|
4285
|
+
primitiveElement,
|
|
4286
|
+
elements
|
|
4287
|
+
}) {
|
|
4288
|
+
const trace = su(elements).source_trace.get(
|
|
4289
|
+
primitiveElement?.source_trace_id
|
|
4290
|
+
);
|
|
4291
|
+
const traceLength = primitiveElement.trace_length;
|
|
4292
|
+
const hasTraceLength = typeof traceLength === "number";
|
|
4293
|
+
const maxLength = trace?.max_length;
|
|
4294
|
+
const text = hasTraceLength ? `${traceLength.toFixed(3)}${typeof maxLength === "number" ? ` / ${maxLength}` : ""} mm` : "";
|
|
4295
|
+
const name = getAssociatedTraceName({ primitiveElement, elements }) ?? getNonEmptyName(trace?.display_name);
|
|
4296
|
+
if (!text && !name) return null;
|
|
4297
|
+
const isOverLength = Boolean(
|
|
4298
|
+
hasTraceLength && typeof maxLength === "number" && traceLength > maxLength
|
|
4299
|
+
);
|
|
4300
|
+
return {
|
|
4301
|
+
text,
|
|
4302
|
+
name,
|
|
4303
|
+
isOverLength
|
|
4304
|
+
};
|
|
4305
|
+
}
|
|
4306
|
+
|
|
4261
4307
|
// src/lib/x-ray-net.ts
|
|
4262
4308
|
function getElementNetId(element, connectivityMap) {
|
|
4263
4309
|
if (!element) return;
|
|
@@ -4282,6 +4328,53 @@ function isXRayCopper(element) {
|
|
|
4282
4328
|
element.type
|
|
4283
4329
|
);
|
|
4284
4330
|
}
|
|
4331
|
+
function getXRayDisplayName(element, elements, connectivityMap) {
|
|
4332
|
+
const directName = element.type === "pcb_trace" ? getAssociatedTraceName({ primitiveElement: element, elements }) : null;
|
|
4333
|
+
if (directName) return directName;
|
|
4334
|
+
const netId = getElementNetId(element, connectivityMap);
|
|
4335
|
+
const connected = netId ? elements.filter(
|
|
4336
|
+
(candidate) => getElementNetId(candidate, connectivityMap) === netId
|
|
4337
|
+
) : [];
|
|
4338
|
+
for (const type of ["source_net", "source_trace"]) {
|
|
4339
|
+
for (const candidate of connected) {
|
|
4340
|
+
if (candidate.type === type && "name" in candidate && typeof candidate.name === "string" && candidate.name.trim())
|
|
4341
|
+
return candidate.name.trim();
|
|
4342
|
+
}
|
|
4343
|
+
}
|
|
4344
|
+
if (element.type === "pcb_trace") {
|
|
4345
|
+
const label = getTraceOverlayInfo({
|
|
4346
|
+
primitiveElement: element,
|
|
4347
|
+
elements
|
|
4348
|
+
})?.name;
|
|
4349
|
+
if (label) return label;
|
|
4350
|
+
}
|
|
4351
|
+
for (const candidate of connected) {
|
|
4352
|
+
if (candidate.type === "source_trace" && candidate.display_name?.trim())
|
|
4353
|
+
return candidate.display_name.trim();
|
|
4354
|
+
}
|
|
4355
|
+
return "Net";
|
|
4356
|
+
}
|
|
4357
|
+
function getXRayGroups(netId, elements, connectivityMap) {
|
|
4358
|
+
return elements.flatMap((element) => {
|
|
4359
|
+
if (element.type !== "source_bus") return [];
|
|
4360
|
+
const netIds = [
|
|
4361
|
+
...new Set(
|
|
4362
|
+
element.source_trace_ids.flatMap((id) => {
|
|
4363
|
+
const net = connectivityMap.getNetConnectedToId(id);
|
|
4364
|
+
return net ? [net] : [];
|
|
4365
|
+
})
|
|
4366
|
+
)
|
|
4367
|
+
];
|
|
4368
|
+
if (!netIds.includes(netId)) return [];
|
|
4369
|
+
return [
|
|
4370
|
+
{
|
|
4371
|
+
id: element.source_bus_id,
|
|
4372
|
+
name: element.name?.trim() || "Bus",
|
|
4373
|
+
netIds
|
|
4374
|
+
}
|
|
4375
|
+
];
|
|
4376
|
+
});
|
|
4377
|
+
}
|
|
4285
4378
|
|
|
4286
4379
|
// src/lib/webgpu/create-worker.ts
|
|
4287
4380
|
var createWebGpuWorker = async () => {
|
|
@@ -10073,52 +10166,6 @@ var PanelAnchorOffsetOverlay = ({
|
|
|
10073
10166
|
);
|
|
10074
10167
|
};
|
|
10075
10168
|
|
|
10076
|
-
// src/lib/get-trace-overlay-text.ts
|
|
10077
|
-
var getNonEmptyName = (name) => name?.trim() || null;
|
|
10078
|
-
function getAssociatedTraceName({
|
|
10079
|
-
primitiveElement,
|
|
10080
|
-
elements
|
|
10081
|
-
}) {
|
|
10082
|
-
const sourceElementId = primitiveElement.source_trace_id;
|
|
10083
|
-
if (!sourceElementId) return null;
|
|
10084
|
-
const circuitJson = su(elements);
|
|
10085
|
-
const sourceTrace = circuitJson.source_trace.get(sourceElementId);
|
|
10086
|
-
const sourceTraceName = getNonEmptyName(sourceTrace?.name);
|
|
10087
|
-
if (sourceTraceName) return sourceTraceName;
|
|
10088
|
-
const sourceNet = circuitJson.source_net.get(sourceElementId);
|
|
10089
|
-
const sourceNetName = getNonEmptyName(sourceNet?.name);
|
|
10090
|
-
if (sourceNetName) return sourceNetName;
|
|
10091
|
-
for (const sourceNetId of sourceTrace?.connected_source_net_ids ?? []) {
|
|
10092
|
-
const connectedSourceNetName = getNonEmptyName(
|
|
10093
|
-
circuitJson.source_net.get(sourceNetId)?.name
|
|
10094
|
-
);
|
|
10095
|
-
if (connectedSourceNetName) return connectedSourceNetName;
|
|
10096
|
-
}
|
|
10097
|
-
return null;
|
|
10098
|
-
}
|
|
10099
|
-
function getTraceOverlayInfo({
|
|
10100
|
-
primitiveElement,
|
|
10101
|
-
elements
|
|
10102
|
-
}) {
|
|
10103
|
-
const trace = su(elements).source_trace.get(
|
|
10104
|
-
primitiveElement?.source_trace_id
|
|
10105
|
-
);
|
|
10106
|
-
const traceLength = primitiveElement.trace_length;
|
|
10107
|
-
const hasTraceLength = typeof traceLength === "number";
|
|
10108
|
-
const maxLength = trace?.max_length;
|
|
10109
|
-
const text = hasTraceLength ? `${traceLength.toFixed(3)}${typeof maxLength === "number" ? ` / ${maxLength}` : ""} mm` : "";
|
|
10110
|
-
const name = getAssociatedTraceName({ primitiveElement, elements }) ?? getNonEmptyName(trace?.display_name);
|
|
10111
|
-
if (!text && !name) return null;
|
|
10112
|
-
const isOverLength = Boolean(
|
|
10113
|
-
hasTraceLength && typeof maxLength === "number" && traceLength > maxLength
|
|
10114
|
-
);
|
|
10115
|
-
return {
|
|
10116
|
-
text,
|
|
10117
|
-
name,
|
|
10118
|
-
isOverLength
|
|
10119
|
-
};
|
|
10120
|
-
}
|
|
10121
|
-
|
|
10122
10169
|
// src/lib/filter-traces-if-multiple.ts
|
|
10123
10170
|
function filterTracesIfMultiple(filterTraces) {
|
|
10124
10171
|
const { primitives, is_showing_multiple_traces_length, elements } = filterTraces;
|
|
@@ -11047,7 +11094,7 @@ import { css as css3 } from "@emotion/css";
|
|
|
11047
11094
|
// package.json
|
|
11048
11095
|
var package_default = {
|
|
11049
11096
|
name: "@tscircuit/pcb-viewer",
|
|
11050
|
-
version: "1.11.
|
|
11097
|
+
version: "1.11.403",
|
|
11051
11098
|
main: "dist/index.js",
|
|
11052
11099
|
type: "module",
|
|
11053
11100
|
repository: {
|
|
@@ -11244,6 +11291,9 @@ var VisibilityContextMenu = ({
|
|
|
11244
11291
|
position,
|
|
11245
11292
|
onClose,
|
|
11246
11293
|
onXRayNet,
|
|
11294
|
+
xRayGroups = [],
|
|
11295
|
+
onXRayGroup,
|
|
11296
|
+
xRayDisplayName = "Net",
|
|
11247
11297
|
onExitXRayNet
|
|
11248
11298
|
}) => {
|
|
11249
11299
|
const engine = useRenderingEngine();
|
|
@@ -11348,19 +11398,41 @@ var VisibilityContextMenu = ({
|
|
|
11348
11398
|
...stacked ? { overflowY: "auto" } : {}
|
|
11349
11399
|
},
|
|
11350
11400
|
children: [
|
|
11351
|
-
onXRayNet && /* @__PURE__ */
|
|
11401
|
+
onXRayNet && /* @__PURE__ */ jsxs15(
|
|
11352
11402
|
"button",
|
|
11353
11403
|
{
|
|
11354
11404
|
type: "button",
|
|
11355
11405
|
role: "menuitem",
|
|
11356
11406
|
className: itemStyle,
|
|
11407
|
+
style: { whiteSpace: "normal", overflowWrap: "anywhere" },
|
|
11357
11408
|
onClick: () => {
|
|
11358
11409
|
onXRayNet();
|
|
11359
11410
|
onClose();
|
|
11360
11411
|
},
|
|
11361
|
-
children:
|
|
11412
|
+
children: [
|
|
11413
|
+
"X-Ray ",
|
|
11414
|
+
xRayDisplayName
|
|
11415
|
+
]
|
|
11362
11416
|
}
|
|
11363
11417
|
),
|
|
11418
|
+
onXRayGroup && xRayGroups.map((group) => /* @__PURE__ */ jsxs15(
|
|
11419
|
+
"button",
|
|
11420
|
+
{
|
|
11421
|
+
type: "button",
|
|
11422
|
+
role: "menuitem",
|
|
11423
|
+
className: itemStyle,
|
|
11424
|
+
style: { whiteSpace: "normal", overflowWrap: "anywhere" },
|
|
11425
|
+
onClick: () => {
|
|
11426
|
+
onXRayGroup(group);
|
|
11427
|
+
onClose();
|
|
11428
|
+
},
|
|
11429
|
+
children: [
|
|
11430
|
+
"X-Ray ",
|
|
11431
|
+
group.name
|
|
11432
|
+
]
|
|
11433
|
+
},
|
|
11434
|
+
group.id
|
|
11435
|
+
)),
|
|
11364
11436
|
onExitXRayNet && /* @__PURE__ */ jsx20(
|
|
11365
11437
|
"button",
|
|
11366
11438
|
{
|
|
@@ -12197,7 +12269,9 @@ var ToolbarOverlay = ({
|
|
|
12197
12269
|
setFocusedErrorId: s.setFocusedErrorId
|
|
12198
12270
|
}));
|
|
12199
12271
|
const [contextMenuPosition, setContextMenuPosition] = useState12(null);
|
|
12272
|
+
const [contextGroups, setContextGroups] = useState12([]);
|
|
12200
12273
|
const [contextNetId, setContextNetId] = useState12();
|
|
12274
|
+
const [contextNetDisplayName, setContextNetDisplayName] = useState12("Net");
|
|
12201
12275
|
const pointerStart = useRef14(null);
|
|
12202
12276
|
const inEditMode = useGlobalStore((s) => s.in_edit_mode);
|
|
12203
12277
|
const netAtEvent = (event) => {
|
|
@@ -12357,13 +12431,16 @@ var ToolbarOverlay = ({
|
|
|
12357
12431
|
const start = pointerStart.current;
|
|
12358
12432
|
if (!start || Math.hypot(event.clientX - start.x, event.clientY - start.y) > 4)
|
|
12359
12433
|
return;
|
|
12360
|
-
const
|
|
12361
|
-
if (!
|
|
12434
|
+
const hit = netAtEvent(event);
|
|
12435
|
+
if (!hit) return;
|
|
12436
|
+
const net = hit.netId;
|
|
12362
12437
|
if (xRayNetIds.includes(net)) {
|
|
12363
12438
|
onXRayNetsChange?.(xRayNetIds.filter((id) => id !== net));
|
|
12364
12439
|
closeContextMenu();
|
|
12365
12440
|
} else {
|
|
12366
12441
|
setContextNetId(net);
|
|
12442
|
+
setContextNetDisplayName(hit.displayName);
|
|
12443
|
+
setContextGroups(hit.groups);
|
|
12367
12444
|
onContextMenuOpenChange?.(true);
|
|
12368
12445
|
setContextMenuPosition({ x: event.clientX, y: event.clientY });
|
|
12369
12446
|
}
|
|
@@ -12375,7 +12452,10 @@ var ToolbarOverlay = ({
|
|
|
12375
12452
|
onContextMenu: (event) => {
|
|
12376
12453
|
event.preventDefault();
|
|
12377
12454
|
event.stopPropagation();
|
|
12378
|
-
|
|
12455
|
+
const hit = netAtEvent(event);
|
|
12456
|
+
setContextNetId(hit?.netId);
|
|
12457
|
+
setContextNetDisplayName(hit?.displayName ?? "Net");
|
|
12458
|
+
setContextGroups(hit?.groups ?? []);
|
|
12379
12459
|
onContextMenuOpenChange?.(true);
|
|
12380
12460
|
setContextMenuPosition({ x: event.clientX, y: event.clientY });
|
|
12381
12461
|
},
|
|
@@ -12390,6 +12470,11 @@ var ToolbarOverlay = ({
|
|
|
12390
12470
|
{
|
|
12391
12471
|
position: contextMenuPosition,
|
|
12392
12472
|
onClose: closeContextMenu,
|
|
12473
|
+
xRayDisplayName: contextNetDisplayName,
|
|
12474
|
+
xRayGroups: contextGroups.filter(
|
|
12475
|
+
(group) => group.netIds.some((id) => !xRayNetIds.includes(id))
|
|
12476
|
+
),
|
|
12477
|
+
onXRayGroup: (group) => onXRayNetsChange?.([.../* @__PURE__ */ new Set([...xRayNetIds, ...group.netIds])]),
|
|
12393
12478
|
onXRayNet: contextNetId && !xRayNetIds.includes(contextNetId) ? () => onXRayNetsChange?.([...xRayNetIds, contextNetId]) : void 0,
|
|
12394
12479
|
onExitXRayNet: xRayNetIds.length > 0 ? () => onXRayNetsChange?.([]) : void 0
|
|
12395
12480
|
}
|
|
@@ -12878,6 +12963,11 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12878
12963
|
);
|
|
12879
12964
|
const getNetAtPoint = (point) => {
|
|
12880
12965
|
if (!transform) return void 0;
|
|
12966
|
+
const describeNet = (netId, element) => ({
|
|
12967
|
+
netId,
|
|
12968
|
+
displayName: getXRayDisplayName(element, elements, connectivityMap),
|
|
12969
|
+
groups: getXRayGroups(netId, elements, connectivityMap)
|
|
12970
|
+
});
|
|
12881
12971
|
const hits = getPrimitivesUnderPoint(
|
|
12882
12972
|
primitivesWithoutInteractionMetadata,
|
|
12883
12973
|
applyToPoint19(inverse6(transform), point),
|
|
@@ -12893,11 +12983,12 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12893
12983
|
);
|
|
12894
12984
|
for (const primitive of copper) {
|
|
12895
12985
|
const net = getElementNetId(primitive._element, connectivityMap);
|
|
12896
|
-
if (net && xRayNetIds.includes(net))
|
|
12986
|
+
if (net && xRayNetIds.includes(net))
|
|
12987
|
+
return describeNet(net, primitive._element);
|
|
12897
12988
|
}
|
|
12898
12989
|
for (const primitive of copper) {
|
|
12899
12990
|
const net = getElementNetId(primitive._element, connectivityMap);
|
|
12900
|
-
if (net) return net;
|
|
12991
|
+
if (net) return describeNet(net, primitive._element);
|
|
12901
12992
|
}
|
|
12902
12993
|
};
|
|
12903
12994
|
const [hoverState, setHoverState] = useState13({
|